page_data.rs

   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                                &centered_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                                &centered_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::SectionHeader("Terminal Panel"),
3101                SettingsPageItem::SettingItem(SettingItem {
3102                    title: "Terminal Dock",
3103                    description: "Where to dock the terminal panel",
3104                    field: Box::new(SettingField {
3105                        pick: |settings_content| {
3106                            if let Some(terminal) = &settings_content.terminal {
3107                                &terminal.dock
3108                            } else {
3109                                &None
3110                            }
3111                        },
3112                        pick_mut: |settings_content| {
3113                            &mut settings_content.terminal.get_or_insert_default().dock
3114                        },
3115                    }),
3116                    metadata: None,
3117                    files: USER,
3118                }),
3119                SettingsPageItem::SectionHeader("Outline Panel"),
3120                SettingsPageItem::SettingItem(SettingItem {
3121                    title: "Outline Panel Button",
3122                    description: "Show the outline panel button in the status bar",
3123                    field: Box::new(SettingField {
3124                        pick: |settings_content| {
3125                            if let Some(outline_panel) = &settings_content.outline_panel {
3126                                &outline_panel.button
3127                            } else {
3128                                &None
3129                            }
3130                        },
3131                        pick_mut: |settings_content| {
3132                            &mut settings_content
3133                                .outline_panel
3134                                .get_or_insert_default()
3135                                .button
3136                        },
3137                    }),
3138                    metadata: None,
3139                    files: USER,
3140                }),
3141                SettingsPageItem::SettingItem(SettingItem {
3142                    title: "Outline Panel Dock",
3143                    description: "Where to dock the outline panel",
3144                    field: Box::new(SettingField {
3145                        pick: |settings_content| {
3146                            if let Some(outline_panel) = &settings_content.outline_panel {
3147                                &outline_panel.dock
3148                            } else {
3149                                &None
3150                            }
3151                        },
3152                        pick_mut: |settings_content| {
3153                            &mut settings_content.outline_panel.get_or_insert_default().dock
3154                        },
3155                    }),
3156                    metadata: None,
3157                    files: USER,
3158                }),
3159                SettingsPageItem::SettingItem(SettingItem {
3160                    title: "Outline Panel Default Width",
3161                    description: "Default width of the outline panel in pixels",
3162                    field: Box::new(SettingField {
3163                        pick: |settings_content| {
3164                            if let Some(outline_panel) = &settings_content.outline_panel {
3165                                &outline_panel.default_width
3166                            } else {
3167                                &None
3168                            }
3169                        },
3170                        pick_mut: |settings_content| {
3171                            &mut settings_content
3172                                .outline_panel
3173                                .get_or_insert_default()
3174                                .default_width
3175                        },
3176                    }),
3177                    metadata: None,
3178                    files: USER,
3179                }),
3180                SettingsPageItem::SettingItem(SettingItem {
3181                    title: "File Icons",
3182                    description: "Show file icons in the outline panel",
3183                    field: Box::new(SettingField {
3184                        pick: |settings_content| {
3185                            if let Some(outline_panel) = &settings_content.outline_panel {
3186                                &outline_panel.file_icons
3187                            } else {
3188                                &None
3189                            }
3190                        },
3191                        pick_mut: |settings_content| {
3192                            &mut settings_content
3193                                .outline_panel
3194                                .get_or_insert_default()
3195                                .file_icons
3196                        },
3197                    }),
3198                    metadata: None,
3199                    files: USER,
3200                }),
3201                SettingsPageItem::SettingItem(SettingItem {
3202                    title: "Folder Icons",
3203                    description: "Whether to show folder icons or chevrons for directories 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.folder_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                                .folder_icons
3217                        },
3218                    }),
3219                    metadata: None,
3220                    files: USER,
3221                }),
3222                SettingsPageItem::SettingItem(SettingItem {
3223                    title: "Git Status",
3224                    description: "Show the git status 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.git_status
3229                            } else {
3230                                &None
3231                            }
3232                        },
3233                        pick_mut: |settings_content| {
3234                            &mut settings_content
3235                                .outline_panel
3236                                .get_or_insert_default()
3237                                .git_status
3238                        },
3239                    }),
3240                    metadata: None,
3241                    files: USER,
3242                }),
3243                SettingsPageItem::SettingItem(SettingItem {
3244                    title: "Indent Size",
3245                    description: "Amount of indentation for nested items",
3246                    field: Box::new(SettingField {
3247                        pick: |settings_content| {
3248                            if let Some(outline_panel) = &settings_content.outline_panel {
3249                                &outline_panel.indent_size
3250                            } else {
3251                                &None
3252                            }
3253                        },
3254                        pick_mut: |settings_content| {
3255                            &mut settings_content
3256                                .outline_panel
3257                                .get_or_insert_default()
3258                                .indent_size
3259                        },
3260                    }),
3261                    metadata: None,
3262                    files: USER,
3263                }),
3264                SettingsPageItem::SettingItem(SettingItem {
3265                    title: "Auto Reveal Entries",
3266                    description: "Whether to reveal when a corresponding outline entry becomes active",
3267                    field: Box::new(SettingField {
3268                        pick: |settings_content| {
3269                            if let Some(outline_panel) = &settings_content.outline_panel {
3270                                &outline_panel.auto_reveal_entries
3271                            } else {
3272                                &None
3273                            }
3274                        },
3275                        pick_mut: |settings_content| {
3276                            &mut settings_content
3277                                .outline_panel
3278                                .get_or_insert_default()
3279                                .auto_reveal_entries
3280                        },
3281                    }),
3282                    metadata: None,
3283                    files: USER,
3284                }),
3285                SettingsPageItem::SettingItem(SettingItem {
3286                    title: "Auto Fold Directories",
3287                    description: "Whether to fold directories automatically when a directory contains only one subdirectory",
3288                    field: Box::new(SettingField {
3289                        pick: |settings_content| {
3290                            if let Some(outline_panel) = &settings_content.outline_panel {
3291                                &outline_panel.auto_fold_dirs
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_fold_dirs
3301                        },
3302                    }),
3303                    metadata: None,
3304                    files: USER,
3305                }),
3306                SettingsPageItem::SettingItem(SettingItem {
3307                    files: USER,
3308                    title: "Indent Guides Show",
3309                    description: "When to show indent guides in the outline panel",
3310                    field: Box::new(
3311                        SettingField {
3312                            pick: |settings_content| {
3313                                if let Some(outline_panel) = &settings_content.outline_panel {
3314                                    if let Some(indent_guides) = &outline_panel.indent_guides {
3315                                        &indent_guides.show
3316                                    } else {
3317                                        &None
3318                                    }
3319                                } else {
3320                                    &None
3321                                }
3322                            },
3323                            pick_mut: |settings_content| {
3324                                &mut settings_content
3325                                    .outline_panel
3326                                    .get_or_insert_default()
3327                                    .indent_guides
3328                                    .get_or_insert_default()
3329                                    .show
3330                            },
3331                        }
3332                        .unimplemented(),
3333                    ),
3334                    metadata: None,
3335                }),
3336                SettingsPageItem::SectionHeader("Git Panel"),
3337                SettingsPageItem::SettingItem(SettingItem {
3338                    title: "Git Panel Button",
3339                    description: "Show the Git panel button in the status bar",
3340                    field: Box::new(SettingField {
3341                        pick: |settings_content| {
3342                            if let Some(git_panel) = &settings_content.git_panel {
3343                                &git_panel.button
3344                            } else {
3345                                &None
3346                            }
3347                        },
3348                        pick_mut: |settings_content| {
3349                            &mut settings_content.git_panel.get_or_insert_default().button
3350                        },
3351                    }),
3352                    metadata: None,
3353                    files: USER,
3354                }),
3355                SettingsPageItem::SettingItem(SettingItem {
3356                    title: "Git Panel Dock",
3357                    description: "Where to dock the Git panel",
3358                    field: Box::new(SettingField {
3359                        pick: |settings_content| {
3360                            if let Some(git_panel) = &settings_content.git_panel {
3361                                &git_panel.dock
3362                            } else {
3363                                &None
3364                            }
3365                        },
3366                        pick_mut: |settings_content| {
3367                            &mut settings_content.git_panel.get_or_insert_default().dock
3368                        },
3369                    }),
3370                    metadata: None,
3371                    files: USER,
3372                }),
3373                SettingsPageItem::SettingItem(SettingItem {
3374                    title: "Git Panel Default Width",
3375                    description: "Default width of the Git panel in pixels",
3376                    field: Box::new(SettingField {
3377                        pick: |settings_content| {
3378                            if let Some(git_panel) = &settings_content.git_panel {
3379                                &git_panel.default_width
3380                            } else {
3381                                &None
3382                            }
3383                        },
3384                        pick_mut: |settings_content| {
3385                            &mut settings_content
3386                                .git_panel
3387                                .get_or_insert_default()
3388                                .default_width
3389                        },
3390                    }),
3391                    metadata: None,
3392                    files: USER,
3393                }),
3394                SettingsPageItem::SettingItem(SettingItem {
3395                    title: "Git Panel Status Style",
3396                    description: "How entry statuses are displayed",
3397                    field: Box::new(SettingField {
3398                        pick: |settings_content| {
3399                            if let Some(git_panel) = &settings_content.git_panel {
3400                                &git_panel.status_style
3401                            } else {
3402                                &None
3403                            }
3404                        },
3405                        pick_mut: |settings_content| {
3406                            &mut settings_content
3407                                .git_panel
3408                                .get_or_insert_default()
3409                                .status_style
3410                        },
3411                    }),
3412                    metadata: None,
3413                    files: USER,
3414                }),
3415                SettingsPageItem::SettingItem(SettingItem {
3416                    title: "Fallback Branch Name",
3417                    description: "Default branch name will be when init.defaultBranch is not set in git",
3418                    field: Box::new(SettingField {
3419                        pick: |settings_content| {
3420                            if let Some(git_panel) = &settings_content.git_panel {
3421                                &git_panel.fallback_branch_name
3422                            } else {
3423                                &None
3424                            }
3425                        },
3426                        pick_mut: |settings_content| {
3427                            &mut settings_content
3428                                .git_panel
3429                                .get_or_insert_default()
3430                                .fallback_branch_name
3431                        },
3432                    }),
3433                    metadata: None,
3434                    files: USER,
3435                }),
3436                SettingsPageItem::SettingItem(SettingItem {
3437                    title: "Sort By Path",
3438                    description: "Enable to sort entries in the panel by path, disable to sort by status",
3439                    field: Box::new(SettingField {
3440                        pick: |settings_content| {
3441                            if let Some(git_panel) = &settings_content.git_panel {
3442                                &git_panel.sort_by_path
3443                            } else {
3444                                &None
3445                            }
3446                        },
3447                        pick_mut: |settings_content| {
3448                            &mut settings_content
3449                                .git_panel
3450                                .get_or_insert_default()
3451                                .sort_by_path
3452                        },
3453                    }),
3454                    metadata: None,
3455                    files: USER,
3456                }),
3457                SettingsPageItem::SettingItem(SettingItem {
3458                    title: "Collapse Untracked Diff",
3459                    description: "Whether to collapse untracked files in the diff panel",
3460                    field: Box::new(SettingField {
3461                        pick: |settings_content| {
3462                            if let Some(git_panel) = &settings_content.git_panel {
3463                                &git_panel.collapse_untracked_diff
3464                            } else {
3465                                &None
3466                            }
3467                        },
3468                        pick_mut: |settings_content| {
3469                            &mut settings_content
3470                                .git_panel
3471                                .get_or_insert_default()
3472                                .collapse_untracked_diff
3473                        },
3474                    }),
3475                    metadata: None,
3476                    files: USER,
3477                }),
3478                SettingsPageItem::SettingItem(SettingItem {
3479                    title: "Scroll Bar",
3480                    description: "How and when the scrollbar should be displayed",
3481                    field: Box::new(SettingField {
3482                        pick: |settings_content| match &settings_content.git_panel {
3483                            Some(settings::GitPanelSettingsContent {
3484                                scrollbar: Some(scrollbar),
3485                                ..
3486                            }) => &scrollbar.show,
3487                            _ => &None,
3488                        },
3489                        pick_mut: |settings_content| {
3490                            &mut settings_content
3491                                .git_panel
3492                                .get_or_insert_default()
3493                                .scrollbar
3494                                .get_or_insert_default()
3495                                .show
3496                        },
3497                    }),
3498                    metadata: None,
3499                    files: USER,
3500                }),
3501                SettingsPageItem::SectionHeader("Debugger Panel"),
3502                SettingsPageItem::SettingItem(SettingItem {
3503                    title: "Debugger Panel Dock",
3504                    description: "The dock position of the debug panel",
3505                    field: Box::new(SettingField {
3506                        pick: |settings_content| {
3507                            if let Some(debugger) = &settings_content.debugger {
3508                                &debugger.dock
3509                            } else {
3510                                &None
3511                            }
3512                        },
3513                        pick_mut: |settings_content| {
3514                            &mut settings_content.debugger.get_or_insert_default().dock
3515                        },
3516                    }),
3517                    metadata: None,
3518                    files: USER,
3519                }),
3520                SettingsPageItem::SectionHeader("Notification Panel"),
3521                SettingsPageItem::SettingItem(SettingItem {
3522                    title: "Notification Panel Button",
3523                    description: "Show the notification panel button in the status bar",
3524                    field: Box::new(SettingField {
3525                        pick: |settings_content| {
3526                            if let Some(notification_panel) = &settings_content.notification_panel {
3527                                &notification_panel.button
3528                            } else {
3529                                &None
3530                            }
3531                        },
3532                        pick_mut: |settings_content| {
3533                            &mut settings_content
3534                                .notification_panel
3535                                .get_or_insert_default()
3536                                .button
3537                        },
3538                    }),
3539                    metadata: None,
3540                    files: USER,
3541                }),
3542                SettingsPageItem::SettingItem(SettingItem {
3543                    title: "Notification Panel Dock",
3544                    description: "Where to dock the notification panel",
3545                    field: Box::new(SettingField {
3546                        pick: |settings_content| {
3547                            if let Some(notification_panel) = &settings_content.notification_panel {
3548                                &notification_panel.dock
3549                            } else {
3550                                &None
3551                            }
3552                        },
3553                        pick_mut: |settings_content| {
3554                            &mut settings_content
3555                                .notification_panel
3556                                .get_or_insert_default()
3557                                .dock
3558                        },
3559                    }),
3560                    metadata: None,
3561                    files: USER,
3562                }),
3563                SettingsPageItem::SettingItem(SettingItem {
3564                    title: "Notification Panel Default Width",
3565                    description: "Default width of the notification panel in pixels",
3566                    field: Box::new(SettingField {
3567                        pick: |settings_content| {
3568                            if let Some(notification_panel) = &settings_content.notification_panel {
3569                                &notification_panel.default_width
3570                            } else {
3571                                &None
3572                            }
3573                        },
3574                        pick_mut: |settings_content| {
3575                            &mut settings_content
3576                                .notification_panel
3577                                .get_or_insert_default()
3578                                .default_width
3579                        },
3580                    }),
3581                    metadata: None,
3582                    files: USER,
3583                }),
3584                SettingsPageItem::SectionHeader("Collaboration Panel"),
3585                SettingsPageItem::SettingItem(SettingItem {
3586                    title: "Collaboration Panel Button",
3587                    description: "Show the collaboration panel button in the status bar",
3588                    field: Box::new(SettingField {
3589                        pick: |settings_content| {
3590                            if let Some(collaboration_panel) = &settings_content.collaboration_panel
3591                            {
3592                                &collaboration_panel.button
3593                            } else {
3594                                &None
3595                            }
3596                        },
3597                        pick_mut: |settings_content| {
3598                            &mut settings_content
3599                                .collaboration_panel
3600                                .get_or_insert_default()
3601                                .button
3602                        },
3603                    }),
3604                    metadata: None,
3605                    files: USER,
3606                }),
3607                SettingsPageItem::SettingItem(SettingItem {
3608                    title: "Collaboration Panel Dock",
3609                    description: "Where to dock the collaboration panel",
3610                    field: Box::new(SettingField {
3611                        pick: |settings_content| {
3612                            if let Some(collaboration_panel) = &settings_content.collaboration_panel
3613                            {
3614                                &collaboration_panel.dock
3615                            } else {
3616                                &None
3617                            }
3618                        },
3619                        pick_mut: |settings_content| {
3620                            &mut settings_content
3621                                .collaboration_panel
3622                                .get_or_insert_default()
3623                                .dock
3624                        },
3625                    }),
3626                    metadata: None,
3627                    files: USER,
3628                }),
3629                SettingsPageItem::SettingItem(SettingItem {
3630                    title: "Collaboration Panel Default Width",
3631                    description: "Default width of the collaboration panel in pixels",
3632                    field: Box::new(SettingField {
3633                        pick: |settings_content| {
3634                            if let Some(collaboration_panel) = &settings_content.collaboration_panel
3635                            {
3636                                &collaboration_panel.default_width
3637                            } else {
3638                                &None
3639                            }
3640                        },
3641                        pick_mut: |settings_content| {
3642                            &mut settings_content
3643                                .collaboration_panel
3644                                .get_or_insert_default()
3645                                .default_width
3646                        },
3647                    }),
3648                    metadata: None,
3649                    files: USER,
3650                }),
3651                SettingsPageItem::SectionHeader("Agent Panel"),
3652                SettingsPageItem::SettingItem(SettingItem {
3653                    title: "Agent Panel Button",
3654                    description: "Whether to show the agent panel button in the status bar",
3655                    field: Box::new(SettingField {
3656                        pick: |settings_content| {
3657                            if let Some(agent) = &settings_content.agent {
3658                                &agent.button
3659                            } else {
3660                                &None
3661                            }
3662                        },
3663                        pick_mut: |settings_content| {
3664                            &mut settings_content.agent.get_or_insert_default().button
3665                        },
3666                    }),
3667                    metadata: None,
3668                    files: USER,
3669                }),
3670                SettingsPageItem::SettingItem(SettingItem {
3671                    title: "Agent Panel Dock",
3672                    description: "Where to dock the agent panel.",
3673                    field: Box::new(SettingField {
3674                        pick: |settings_content| {
3675                            if let Some(agent) = &settings_content.agent {
3676                                &agent.dock
3677                            } else {
3678                                &None
3679                            }
3680                        },
3681                        pick_mut: |settings_content| {
3682                            &mut settings_content.agent.get_or_insert_default().dock
3683                        },
3684                    }),
3685                    metadata: None,
3686                    files: USER,
3687                }),
3688                SettingsPageItem::SettingItem(SettingItem {
3689                    title: "Agent Panel Default Width",
3690                    description: "Default width when the agent panel is docked to the left or right",
3691                    field: Box::new(SettingField {
3692                        pick: |settings_content| {
3693                            if let Some(agent) = &settings_content.agent {
3694                                &agent.default_width
3695                            } else {
3696                                &None
3697                            }
3698                        },
3699                        pick_mut: |settings_content| {
3700                            &mut settings_content.agent.get_or_insert_default().default_width
3701                        },
3702                    }),
3703                    metadata: None,
3704                    files: USER,
3705                }),
3706                SettingsPageItem::SettingItem(SettingItem {
3707                    title: "Agent Panel Default Height",
3708                    description: "Default height when the agent panel is docked to the bottom",
3709                    field: Box::new(SettingField {
3710                        pick: |settings_content| {
3711                            if let Some(agent) = &settings_content.agent {
3712                                &agent.default_height
3713                            } else {
3714                                &None
3715                            }
3716                        },
3717                        pick_mut: |settings_content| {
3718                            &mut settings_content
3719                                .agent
3720                                .get_or_insert_default()
3721                                .default_height
3722                        },
3723                    }),
3724                    metadata: None,
3725                    files: USER,
3726                }),
3727            ],
3728        },
3729        SettingsPage {
3730            title: "Debugger",
3731            items: vec![
3732                SettingsPageItem::SectionHeader("General"),
3733                SettingsPageItem::SettingItem(SettingItem {
3734                    title: "Stepping Granularity",
3735                    description: "Determines the stepping granularity for debug operations",
3736                    field: Box::new(SettingField {
3737                        pick: |settings_content| {
3738                            if let Some(debugger) = &settings_content.debugger {
3739                                &debugger.stepping_granularity
3740                            } else {
3741                                &None
3742                            }
3743                        },
3744                        pick_mut: |settings_content| {
3745                            &mut settings_content
3746                                .debugger
3747                                .get_or_insert_default()
3748                                .stepping_granularity
3749                        },
3750                    }),
3751                    metadata: None,
3752                    files: USER,
3753                }),
3754                SettingsPageItem::SettingItem(SettingItem {
3755                    title: "Save Breakpoints",
3756                    description: "Whether breakpoints should be reused across Zed sessions",
3757                    field: Box::new(SettingField {
3758                        pick: |settings_content| {
3759                            if let Some(debugger) = &settings_content.debugger {
3760                                &debugger.save_breakpoints
3761                            } else {
3762                                &None
3763                            }
3764                        },
3765                        pick_mut: |settings_content| {
3766                            &mut settings_content
3767                                .debugger
3768                                .get_or_insert_default()
3769                                .save_breakpoints
3770                        },
3771                    }),
3772                    metadata: None,
3773                    files: USER,
3774                }),
3775                SettingsPageItem::SettingItem(SettingItem {
3776                    title: "Timeout",
3777                    description: "Time in milliseconds until timeout error when connecting to a TCP debug adapter",
3778                    field: Box::new(SettingField {
3779                        pick: |settings_content| {
3780                            if let Some(debugger) = &settings_content.debugger {
3781                                &debugger.timeout
3782                            } else {
3783                                &None
3784                            }
3785                        },
3786                        pick_mut: |settings_content| {
3787                            &mut settings_content.debugger.get_or_insert_default().timeout
3788                        },
3789                    }),
3790                    metadata: None,
3791                    files: USER,
3792                }),
3793                SettingsPageItem::SettingItem(SettingItem {
3794                    title: "Log DAP Communications",
3795                    description: "Whether to log messages between active debug adapters and Zed",
3796                    field: Box::new(SettingField {
3797                        pick: |settings_content| {
3798                            if let Some(debugger) = &settings_content.debugger {
3799                                &debugger.log_dap_communications
3800                            } else {
3801                                &None
3802                            }
3803                        },
3804                        pick_mut: |settings_content| {
3805                            &mut settings_content
3806                                .debugger
3807                                .get_or_insert_default()
3808                                .log_dap_communications
3809                        },
3810                    }),
3811                    metadata: None,
3812                    files: USER,
3813                }),
3814                SettingsPageItem::SettingItem(SettingItem {
3815                    title: "Format DAP Log Messages",
3816                    description: "Whether to format DAP messages when adding them to debug adapter logger",
3817                    field: Box::new(SettingField {
3818                        pick: |settings_content| {
3819                            if let Some(debugger) = &settings_content.debugger {
3820                                &debugger.format_dap_log_messages
3821                            } else {
3822                                &None
3823                            }
3824                        },
3825                        pick_mut: |settings_content| {
3826                            &mut settings_content
3827                                .debugger
3828                                .get_or_insert_default()
3829                                .format_dap_log_messages
3830                        },
3831                    }),
3832                    metadata: None,
3833                    files: USER,
3834                }),
3835            ],
3836        },
3837        SettingsPage {
3838            title: "Terminal",
3839            items: vec![
3840                SettingsPageItem::SectionHeader("Environment"),
3841                SettingsPageItem::SettingItem(SettingItem {
3842                    title: "Shell",
3843                    description: "What shell to use when opening a terminal",
3844                    field: Box::new(
3845                        SettingField {
3846                            pick: |settings_content| {
3847                                if let Some(terminal) = &settings_content.terminal {
3848                                    &terminal.project.shell
3849                                } else {
3850                                    &None
3851                                }
3852                            },
3853                            pick_mut: |settings_content| {
3854                                &mut settings_content
3855                                    .terminal
3856                                    .get_or_insert_default()
3857                                    .project
3858                                    .shell
3859                            },
3860                        }
3861                        .unimplemented(),
3862                    ),
3863                    metadata: None,
3864                    files: USER | LOCAL,
3865                }),
3866                SettingsPageItem::SettingItem(SettingItem {
3867                    title: "Working Directory",
3868                    description: "What working directory to use when launching the terminal",
3869                    field: Box::new(
3870                        SettingField {
3871                            pick: |settings_content| {
3872                                if let Some(terminal) = &settings_content.terminal {
3873                                    &terminal.project.working_directory
3874                                } else {
3875                                    &None
3876                                }
3877                            },
3878                            pick_mut: |settings_content| {
3879                                &mut settings_content
3880                                    .terminal
3881                                    .get_or_insert_default()
3882                                    .project
3883                                    .working_directory
3884                            },
3885                        }
3886                        .unimplemented(),
3887                    ),
3888                    metadata: None,
3889                    files: USER | LOCAL,
3890                }),
3891                SettingsPageItem::SettingItem(SettingItem {
3892                    title: "Environment Variables",
3893                    description: "Key-value pairs to add to the terminal's environment",
3894                    field: Box::new(
3895                        SettingField {
3896                            pick: |settings_content| {
3897                                if let Some(terminal) = &settings_content.terminal {
3898                                    &terminal.project.env
3899                                } else {
3900                                    &None
3901                                }
3902                            },
3903                            pick_mut: |settings_content| {
3904                                &mut settings_content
3905                                    .terminal
3906                                    .get_or_insert_default()
3907                                    .project
3908                                    .env
3909                            },
3910                        }
3911                        .unimplemented(),
3912                    ),
3913                    metadata: None,
3914                    files: USER | LOCAL,
3915                }),
3916                SettingsPageItem::SettingItem(SettingItem {
3917                    title: "Detect Virtual Environment",
3918                    description: "Activates the python virtual environment, if one is found, in the terminal's working directory",
3919                    field: Box::new(
3920                        SettingField {
3921                            pick: |settings_content| {
3922                                if let Some(terminal) = &settings_content.terminal {
3923                                    &terminal.project.detect_venv
3924                                } else {
3925                                    &None
3926                                }
3927                            },
3928                            pick_mut: |settings_content| {
3929                                &mut settings_content
3930                                    .terminal
3931                                    .get_or_insert_default()
3932                                    .project
3933                                    .detect_venv
3934                            },
3935                        }
3936                        .unimplemented(),
3937                    ),
3938                    metadata: None,
3939                    files: USER | LOCAL,
3940                }),
3941                SettingsPageItem::SectionHeader("Font"),
3942                SettingsPageItem::SettingItem(SettingItem {
3943                    title: "Font Size",
3944                    description: "Font size for terminal text. If not set, defaults to buffer font size",
3945                    field: Box::new(SettingField {
3946                        pick: |settings_content| {
3947                            if let Some(terminal) = &settings_content.terminal
3948                                && terminal.font_size.is_some()
3949                            {
3950                                &terminal.font_size
3951                            } else if settings_content.theme.buffer_font_size.is_some() {
3952                                &settings_content.theme.buffer_font_size
3953                            } else {
3954                                &None
3955                            }
3956                        },
3957                        pick_mut: |settings_content| {
3958                            &mut settings_content.terminal.get_or_insert_default().font_size
3959                        },
3960                    }),
3961                    metadata: None,
3962                    files: USER,
3963                }),
3964                SettingsPageItem::SettingItem(SettingItem {
3965                    title: "Font Family",
3966                    description: "Font family for terminal text. If not set, defaults to buffer font family",
3967                    field: Box::new(SettingField {
3968                        pick: |settings_content| {
3969                            if let Some(terminal) = &settings_content.terminal
3970                                && terminal.font_family.is_some()
3971                            {
3972                                &terminal.font_family
3973                            } else if settings_content.theme.buffer_font_family.is_some() {
3974                                &settings_content.theme.buffer_font_family
3975                            } else {
3976                                &None
3977                            }
3978                        },
3979                        pick_mut: |settings_content| {
3980                            &mut settings_content
3981                                .terminal
3982                                .get_or_insert_default()
3983                                .font_family
3984                        },
3985                    }),
3986                    metadata: None,
3987                    files: USER,
3988                }),
3989                SettingsPageItem::SettingItem(SettingItem {
3990                    title: "Font Fallbacks",
3991                    description: "Font fallbacks for terminal text. If not set, defaults to buffer font fallbacks",
3992                    field: Box::new(
3993                        SettingField {
3994                            pick: |settings_content| {
3995                                if let Some(terminal) = &settings_content.terminal {
3996                                    &terminal.font_fallbacks
3997                                } else {
3998                                    &None
3999                                }
4000                            },
4001                            pick_mut: |settings_content| {
4002                                &mut settings_content
4003                                    .terminal
4004                                    .get_or_insert_default()
4005                                    .font_fallbacks
4006                            },
4007                        }
4008                        .unimplemented(),
4009                    ),
4010                    metadata: None,
4011                    files: USER,
4012                }),
4013                SettingsPageItem::SettingItem(SettingItem {
4014                    title: "Font Weight",
4015                    description: "Font weight for terminal text in CSS weight units (100-900)",
4016                    field: Box::new(SettingField {
4017                        pick: |settings_content| {
4018                            if let Some(terminal) = &settings_content.terminal {
4019                                &terminal.font_weight
4020                            } else {
4021                                &None
4022                            }
4023                        },
4024                        pick_mut: |settings_content| {
4025                            &mut settings_content
4026                                .terminal
4027                                .get_or_insert_default()
4028                                .font_weight
4029                        },
4030                    }),
4031                    metadata: None,
4032                    files: USER,
4033                }),
4034                SettingsPageItem::SettingItem(SettingItem {
4035                    title: "Font Features",
4036                    description: "Font features for terminal text",
4037                    field: Box::new(
4038                        SettingField {
4039                            pick: |settings_content| {
4040                                if let Some(terminal) = &settings_content.terminal {
4041                                    &terminal.font_features
4042                                } else {
4043                                    &None
4044                                }
4045                            },
4046                            pick_mut: |settings_content| {
4047                                &mut settings_content
4048                                    .terminal
4049                                    .get_or_insert_default()
4050                                    .font_features
4051                            },
4052                        }
4053                        .unimplemented(),
4054                    ),
4055                    metadata: None,
4056                    files: USER,
4057                }),
4058                SettingsPageItem::SectionHeader("Display Settings"),
4059                SettingsPageItem::SettingItem(SettingItem {
4060                    title: "Line Height",
4061                    description: "Line height for terminal text",
4062                    field: Box::new(
4063                        SettingField {
4064                            pick: |settings_content| {
4065                                if let Some(terminal) = &settings_content.terminal {
4066                                    &terminal.line_height
4067                                } else {
4068                                    &None
4069                                }
4070                            },
4071                            pick_mut: |settings_content| {
4072                                &mut settings_content
4073                                    .terminal
4074                                    .get_or_insert_default()
4075                                    .line_height
4076                            },
4077                        }
4078                        .unimplemented(),
4079                    ),
4080                    metadata: None,
4081                    files: USER,
4082                }),
4083                SettingsPageItem::SettingItem(SettingItem {
4084                    title: "Cursor Shape",
4085                    description: "Default cursor shape for the terminal (bar, block, underline, or hollow)",
4086                    field: Box::new(SettingField {
4087                        pick: |settings_content| {
4088                            if let Some(terminal) = &settings_content.terminal {
4089                                &terminal.cursor_shape
4090                            } else {
4091                                &None
4092                            }
4093                        },
4094                        pick_mut: |settings_content| {
4095                            &mut settings_content
4096                                .terminal
4097                                .get_or_insert_default()
4098                                .cursor_shape
4099                        },
4100                    }),
4101                    metadata: None,
4102                    files: USER,
4103                }),
4104                SettingsPageItem::SettingItem(SettingItem {
4105                    title: "Cursor Blinking",
4106                    description: "Sets the cursor blinking behavior in the terminal",
4107                    field: Box::new(SettingField {
4108                        pick: |settings_content| {
4109                            if let Some(terminal) = &settings_content.terminal {
4110                                &terminal.blinking
4111                            } else {
4112                                &None
4113                            }
4114                        },
4115                        pick_mut: |settings_content| {
4116                            &mut settings_content.terminal.get_or_insert_default().blinking
4117                        },
4118                    }),
4119                    metadata: None,
4120                    files: USER,
4121                }),
4122                SettingsPageItem::SettingItem(SettingItem {
4123                    title: "Alternate Scroll",
4124                    description: "Whether Alternate Scroll mode is active by default (converts mouse scroll to arrow keys in apps like vim)",
4125                    field: Box::new(SettingField {
4126                        pick: |settings_content| {
4127                            if let Some(terminal) = &settings_content.terminal {
4128                                &terminal.alternate_scroll
4129                            } else {
4130                                &None
4131                            }
4132                        },
4133                        pick_mut: |settings_content| {
4134                            &mut settings_content
4135                                .terminal
4136                                .get_or_insert_default()
4137                                .alternate_scroll
4138                        },
4139                    }),
4140                    metadata: None,
4141                    files: USER,
4142                }),
4143                SettingsPageItem::SettingItem(SettingItem {
4144                    title: "Minimum Contrast",
4145                    description: "The minimum APCA perceptual contrast between foreground and background colors (0-106)",
4146                    field: Box::new(SettingField {
4147                        pick: |settings_content| {
4148                            if let Some(terminal) = &settings_content.terminal {
4149                                &terminal.minimum_contrast
4150                            } else {
4151                                &None
4152                            }
4153                        },
4154                        pick_mut: |settings_content| {
4155                            &mut settings_content
4156                                .terminal
4157                                .get_or_insert_default()
4158                                .minimum_contrast
4159                        },
4160                    }),
4161                    metadata: None,
4162                    files: USER,
4163                }),
4164                SettingsPageItem::SectionHeader("Behavior Settings"),
4165                SettingsPageItem::SettingItem(SettingItem {
4166                    title: "Option As Meta",
4167                    description: "Whether the option key behaves as the meta key",
4168                    field: Box::new(SettingField {
4169                        pick: |settings_content| {
4170                            if let Some(terminal) = &settings_content.terminal {
4171                                &terminal.option_as_meta
4172                            } else {
4173                                &None
4174                            }
4175                        },
4176                        pick_mut: |settings_content| {
4177                            &mut settings_content
4178                                .terminal
4179                                .get_or_insert_default()
4180                                .option_as_meta
4181                        },
4182                    }),
4183                    metadata: None,
4184                    files: USER,
4185                }),
4186                SettingsPageItem::SettingItem(SettingItem {
4187                    title: "Copy On Select",
4188                    description: "Whether selecting text in the terminal automatically copies to the system clipboard",
4189                    field: Box::new(SettingField {
4190                        pick: |settings_content| {
4191                            if let Some(terminal) = &settings_content.terminal {
4192                                &terminal.copy_on_select
4193                            } else {
4194                                &None
4195                            }
4196                        },
4197                        pick_mut: |settings_content| {
4198                            &mut settings_content
4199                                .terminal
4200                                .get_or_insert_default()
4201                                .copy_on_select
4202                        },
4203                    }),
4204                    metadata: None,
4205                    files: USER,
4206                }),
4207                SettingsPageItem::SettingItem(SettingItem {
4208                    title: "Keep Selection On Copy",
4209                    description: "Whether to keep the text selection after copying it to the clipboard",
4210                    field: Box::new(SettingField {
4211                        pick: |settings_content| {
4212                            if let Some(terminal) = &settings_content.terminal {
4213                                &terminal.keep_selection_on_copy
4214                            } else {
4215                                &None
4216                            }
4217                        },
4218                        pick_mut: |settings_content| {
4219                            &mut settings_content
4220                                .terminal
4221                                .get_or_insert_default()
4222                                .keep_selection_on_copy
4223                        },
4224                    }),
4225                    metadata: None,
4226                    files: USER,
4227                }),
4228                SettingsPageItem::SectionHeader("Layout Settings"),
4229                SettingsPageItem::SettingItem(SettingItem {
4230                    title: "Default Width",
4231                    description: "Default width when the terminal is docked to the left or right (in pixels)",
4232                    field: Box::new(SettingField {
4233                        pick: |settings_content| {
4234                            if let Some(terminal) = &settings_content.terminal {
4235                                &terminal.default_width
4236                            } else {
4237                                &None
4238                            }
4239                        },
4240                        pick_mut: |settings_content| {
4241                            &mut settings_content
4242                                .terminal
4243                                .get_or_insert_default()
4244                                .default_width
4245                        },
4246                    }),
4247                    metadata: None,
4248                    files: USER,
4249                }),
4250                SettingsPageItem::SettingItem(SettingItem {
4251                    title: "Default Height",
4252                    description: "Default height when the terminal is docked to the bottom (in pixels)",
4253                    field: Box::new(SettingField {
4254                        pick: |settings_content| {
4255                            if let Some(terminal) = &settings_content.terminal {
4256                                &terminal.default_height
4257                            } else {
4258                                &None
4259                            }
4260                        },
4261                        pick_mut: |settings_content| {
4262                            &mut settings_content
4263                                .terminal
4264                                .get_or_insert_default()
4265                                .default_height
4266                        },
4267                    }),
4268                    metadata: None,
4269                    files: USER,
4270                }),
4271                SettingsPageItem::SectionHeader("Advanced Settings"),
4272                SettingsPageItem::SettingItem(SettingItem {
4273                    title: "Max Scroll History Lines",
4274                    description: "Maximum number of lines to keep in scrollback history (max: 100,000; 0 disables scrolling)",
4275                    field: Box::new(SettingField {
4276                        pick: |settings_content| {
4277                            if let Some(terminal) = &settings_content.terminal {
4278                                &terminal.max_scroll_history_lines
4279                            } else {
4280                                &None
4281                            }
4282                        },
4283                        pick_mut: |settings_content| {
4284                            &mut settings_content
4285                                .terminal
4286                                .get_or_insert_default()
4287                                .max_scroll_history_lines
4288                        },
4289                    }),
4290                    metadata: None,
4291                    files: USER,
4292                }),
4293                SettingsPageItem::SectionHeader("Toolbar"),
4294                SettingsPageItem::SettingItem(SettingItem {
4295                    title: "Breadcrumbs",
4296                    description: "Display the terminal title in breadcrumbs inside the terminal pane",
4297                    field: Box::new(SettingField {
4298                        pick: |settings_content| {
4299                            if let Some(terminal) = &settings_content.terminal {
4300                                if let Some(toolbar) = &terminal.toolbar {
4301                                    &toolbar.breadcrumbs
4302                                } else {
4303                                    &None
4304                                }
4305                            } else {
4306                                &None
4307                            }
4308                        },
4309                        pick_mut: |settings_content| {
4310                            &mut settings_content
4311                                .terminal
4312                                .get_or_insert_default()
4313                                .toolbar
4314                                .get_or_insert_default()
4315                                .breadcrumbs
4316                        },
4317                    }),
4318                    metadata: None,
4319                    files: USER,
4320                }),
4321                SettingsPageItem::SectionHeader("Scrollbar"),
4322                SettingsPageItem::SettingItem(SettingItem {
4323                    title: "Show Scrollbar",
4324                    description: "When to show the scrollbar in the terminal",
4325                    field: Box::new(SettingField {
4326                        pick: |settings_content| {
4327                            if let Some(terminal) = &settings_content.terminal
4328                                && let Some(scrollbar) = &terminal.scrollbar
4329                                && scrollbar.show.is_some()
4330                            {
4331                                &scrollbar.show
4332                            } else if let Some(scrollbar) = &settings_content.editor.scrollbar {
4333                                &scrollbar.show
4334                            } else {
4335                                &None
4336                            }
4337                        },
4338                        pick_mut: |settings_content| {
4339                            &mut settings_content
4340                                .terminal
4341                                .get_or_insert_default()
4342                                .scrollbar
4343                                .get_or_insert_default()
4344                                .show
4345                        },
4346                    }),
4347                    metadata: None,
4348                    files: USER,
4349                }),
4350            ],
4351        },
4352        SettingsPage {
4353            title: "Version Control",
4354            items: vec![
4355                SettingsPageItem::SectionHeader("Git Gutter"),
4356                SettingsPageItem::SettingItem(SettingItem {
4357                    title: "Visibilility",
4358                    description: "Control whether git status is shown in the editor's gutter",
4359                    field: Box::new(SettingField {
4360                        pick: |settings_content| {
4361                            if let Some(git) = &settings_content.git {
4362                                &git.git_gutter
4363                            } else {
4364                                &None
4365                            }
4366                        },
4367                        pick_mut: |settings_content| {
4368                            &mut settings_content.git.get_or_insert_default().git_gutter
4369                        },
4370                    }),
4371                    metadata: None,
4372                    files: USER,
4373                }),
4374                // todo(settings_ui): Figure out the right default for this value in default.json
4375                SettingsPageItem::SettingItem(SettingItem {
4376                    title: "Debounce",
4377                    description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter",
4378                    field: Box::new(SettingField {
4379                        pick: |settings_content| {
4380                            if let Some(git) = &settings_content.git {
4381                                &git.gutter_debounce
4382                            } else {
4383                                &None
4384                            }
4385                        },
4386                        pick_mut: |settings_content| {
4387                            &mut settings_content.git.get_or_insert_default().gutter_debounce
4388                        },
4389                    }),
4390                    metadata: None,
4391                    files: USER,
4392                }),
4393                SettingsPageItem::SectionHeader("Inline Git Blame"),
4394                SettingsPageItem::SettingItem(SettingItem {
4395                    title: "Enabled",
4396                    description: "Whether or not to show git blame data inline in the currently focused line",
4397                    field: Box::new(SettingField {
4398                        pick: |settings_content| {
4399                            if let Some(git) = &settings_content.git {
4400                                if let Some(inline_blame) = &git.inline_blame {
4401                                    &inline_blame.enabled
4402                                } else {
4403                                    &None
4404                                }
4405                            } else {
4406                                &None
4407                            }
4408                        },
4409                        pick_mut: |settings_content| {
4410                            &mut settings_content
4411                                .git
4412                                .get_or_insert_default()
4413                                .inline_blame
4414                                .get_or_insert_default()
4415                                .enabled
4416                        },
4417                    }),
4418                    metadata: None,
4419                    files: USER,
4420                }),
4421                SettingsPageItem::SettingItem(SettingItem {
4422                    title: "Delay",
4423                    description: "The delay after which the inline blame information is shown",
4424                    field: Box::new(SettingField {
4425                        pick: |settings_content| {
4426                            if let Some(git) = &settings_content.git {
4427                                if let Some(inline_blame) = &git.inline_blame {
4428                                    &inline_blame.delay_ms
4429                                } else {
4430                                    &None
4431                                }
4432                            } else {
4433                                &None
4434                            }
4435                        },
4436                        pick_mut: |settings_content| {
4437                            &mut settings_content
4438                                .git
4439                                .get_or_insert_default()
4440                                .inline_blame
4441                                .get_or_insert_default()
4442                                .delay_ms
4443                        },
4444                    }),
4445                    metadata: None,
4446                    files: USER,
4447                }),
4448                SettingsPageItem::SettingItem(SettingItem {
4449                    title: "Padding",
4450                    description: "Padding between the end of the source line and the start of the inline blame in columns",
4451                    field: Box::new(SettingField {
4452                        pick: |settings_content| {
4453                            if let Some(git) = &settings_content.git {
4454                                if let Some(inline_blame) = &git.inline_blame {
4455                                    &inline_blame.padding
4456                                } else {
4457                                    &None
4458                                }
4459                            } else {
4460                                &None
4461                            }
4462                        },
4463                        pick_mut: |settings_content| {
4464                            &mut settings_content
4465                                .git
4466                                .get_or_insert_default()
4467                                .inline_blame
4468                                .get_or_insert_default()
4469                                .padding
4470                        },
4471                    }),
4472                    metadata: None,
4473                    files: USER,
4474                }),
4475                SettingsPageItem::SettingItem(SettingItem {
4476                    title: "Minimum Column",
4477                    description: "The minimum column number at which to show the inline blame information",
4478                    field: Box::new(SettingField {
4479                        pick: |settings_content| match &settings_content.git {
4480                            Some(settings::GitSettings {
4481                                inline_blame: Some(inline_blame),
4482                                ..
4483                            }) => &inline_blame.min_column,
4484                            _ => &None,
4485                        },
4486                        pick_mut: |settings_content| {
4487                            &mut settings_content
4488                                .git
4489                                .get_or_insert_default()
4490                                .inline_blame
4491                                .get_or_insert_default()
4492                                .min_column
4493                        },
4494                    }),
4495                    metadata: None,
4496                    files: USER,
4497                }),
4498                SettingsPageItem::SettingItem(SettingItem {
4499                    title: "Show Commit Summary",
4500                    description: "Show commit summary as part of the inline blame",
4501                    field: Box::new(SettingField {
4502                        pick: |settings_content| {
4503                            if let Some(git) = &settings_content.git {
4504                                if let Some(inline_blame) = &git.inline_blame {
4505                                    &inline_blame.show_commit_summary
4506                                } else {
4507                                    &None
4508                                }
4509                            } else {
4510                                &None
4511                            }
4512                        },
4513                        pick_mut: |settings_content| {
4514                            &mut settings_content
4515                                .git
4516                                .get_or_insert_default()
4517                                .inline_blame
4518                                .get_or_insert_default()
4519                                .show_commit_summary
4520                        },
4521                    }),
4522                    metadata: None,
4523                    files: USER,
4524                }),
4525                SettingsPageItem::SectionHeader("Git Blame View"),
4526                SettingsPageItem::SettingItem(SettingItem {
4527                    title: "Show Avatar",
4528                    description: "Show the avatar of the author of the commit",
4529                    field: Box::new(SettingField {
4530                        pick: |settings_content| {
4531                            if let Some(git) = &settings_content.git {
4532                                if let Some(blame) = &git.blame {
4533                                    &blame.show_avatar
4534                                } else {
4535                                    &None
4536                                }
4537                            } else {
4538                                &None
4539                            }
4540                        },
4541                        pick_mut: |settings_content| {
4542                            &mut settings_content
4543                                .git
4544                                .get_or_insert_default()
4545                                .blame
4546                                .get_or_insert_default()
4547                                .show_avatar
4548                        },
4549                    }),
4550                    metadata: None,
4551                    files: USER,
4552                }),
4553                SettingsPageItem::SectionHeader("Branch Picker"),
4554                SettingsPageItem::SettingItem(SettingItem {
4555                    title: "Show Author Name",
4556                    description: "Show author name as part of the commit information in branch picker",
4557                    field: Box::new(SettingField {
4558                        pick: |settings_content| {
4559                            if let Some(git) = &settings_content.git {
4560                                if let Some(branch_picker) = &git.branch_picker {
4561                                    &branch_picker.show_author_name
4562                                } else {
4563                                    &None
4564                                }
4565                            } else {
4566                                &None
4567                            }
4568                        },
4569                        pick_mut: |settings_content| {
4570                            &mut settings_content
4571                                .git
4572                                .get_or_insert_default()
4573                                .branch_picker
4574                                .get_or_insert_default()
4575                                .show_author_name
4576                        },
4577                    }),
4578                    metadata: None,
4579                    files: USER,
4580                }),
4581                SettingsPageItem::SectionHeader("Git Hunks"),
4582                SettingsPageItem::SettingItem(SettingItem {
4583                    title: "Hunk Style",
4584                    description: "How git hunks are displayed visually in the editor",
4585                    field: Box::new(SettingField {
4586                        pick: |settings_content| {
4587                            if let Some(git) = &settings_content.git {
4588                                &git.hunk_style
4589                            } else {
4590                                &None
4591                            }
4592                        },
4593                        pick_mut: |settings_content| {
4594                            &mut settings_content.git.get_or_insert_default().hunk_style
4595                        },
4596                    }),
4597                    metadata: None,
4598                    files: USER,
4599                }),
4600            ],
4601        },
4602        SettingsPage {
4603            title: "Collaboration",
4604            items: vec![
4605                SettingsPageItem::SectionHeader("Calls"),
4606                SettingsPageItem::SettingItem(SettingItem {
4607                    title: "Mute On Join",
4608                    description: "Whether the microphone should be muted when joining a channel or a call",
4609                    field: Box::new(SettingField {
4610                        pick: |settings_content| {
4611                            if let Some(calls) = &settings_content.calls {
4612                                &calls.mute_on_join
4613                            } else {
4614                                &None
4615                            }
4616                        },
4617                        pick_mut: |settings_content| {
4618                            &mut settings_content.calls.get_or_insert_default().mute_on_join
4619                        },
4620                    }),
4621                    metadata: None,
4622                    files: USER,
4623                }),
4624                SettingsPageItem::SettingItem(SettingItem {
4625                    title: "Share On Join",
4626                    description: "Whether your current project should be shared when joining an empty channel",
4627                    field: Box::new(SettingField {
4628                        pick: |settings_content| {
4629                            if let Some(calls) = &settings_content.calls {
4630                                &calls.share_on_join
4631                            } else {
4632                                &None
4633                            }
4634                        },
4635                        pick_mut: |settings_content| {
4636                            &mut settings_content.calls.get_or_insert_default().share_on_join
4637                        },
4638                    }),
4639                    metadata: None,
4640                    files: USER,
4641                }),
4642                SettingsPageItem::SectionHeader("Experimental"),
4643                SettingsPageItem::SettingItem(SettingItem {
4644                    title: "Rodio Audio",
4645                    description: "Opt into the new audio system",
4646                    field: Box::new(SettingField {
4647                        pick: |settings_content| {
4648                            if let Some(audio) = &settings_content.audio {
4649                                &audio.rodio_audio
4650                            } else {
4651                                &None
4652                            }
4653                        },
4654                        pick_mut: |settings_content| {
4655                            &mut settings_content.audio.get_or_insert_default().rodio_audio
4656                        },
4657                    }),
4658                    metadata: None,
4659                    files: USER,
4660                }),
4661                SettingsPageItem::SettingItem(SettingItem {
4662                    title: "Auto Microphone Volume",
4663                    description: "Automatically adjust microphone volume (requires Rodio Audio)",
4664                    field: Box::new(SettingField {
4665                        pick: |settings_content| {
4666                            if let Some(audio) = &settings_content.audio {
4667                                &audio.auto_microphone_volume
4668                            } else {
4669                                &None
4670                            }
4671                        },
4672                        pick_mut: |settings_content| {
4673                            &mut settings_content
4674                                .audio
4675                                .get_or_insert_default()
4676                                .auto_microphone_volume
4677                        },
4678                    }),
4679                    metadata: None,
4680                    files: USER,
4681                }),
4682                SettingsPageItem::SettingItem(SettingItem {
4683                    title: "Auto Speaker Volume",
4684                    description: "Automatically adjust volume of other call members (requires Rodio Audio)",
4685                    field: Box::new(SettingField {
4686                        pick: |settings_content| {
4687                            if let Some(audio) = &settings_content.audio {
4688                                &audio.auto_speaker_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_speaker_volume
4698                        },
4699                    }),
4700                    metadata: None,
4701                    files: USER,
4702                }),
4703                SettingsPageItem::SettingItem(SettingItem {
4704                    title: "Denoise",
4705                    description: "Remove background noises (requires Rodio Audio)",
4706                    field: Box::new(SettingField {
4707                        pick: |settings_content| {
4708                            if let Some(audio) = &settings_content.audio {
4709                                &audio.denoise
4710                            } else {
4711                                &None
4712                            }
4713                        },
4714                        pick_mut: |settings_content| {
4715                            &mut settings_content.audio.get_or_insert_default().denoise
4716                        },
4717                    }),
4718                    metadata: None,
4719                    files: USER,
4720                }),
4721                SettingsPageItem::SettingItem(SettingItem {
4722                    title: "Legacy Audio Compatible",
4723                    description: "Use audio parameters compatible with previous versions (requires Rodio Audio)",
4724                    field: Box::new(SettingField {
4725                        pick: |settings_content| {
4726                            if let Some(audio) = &settings_content.audio {
4727                                &audio.legacy_audio_compatible
4728                            } else {
4729                                &None
4730                            }
4731                        },
4732                        pick_mut: |settings_content| {
4733                            &mut settings_content
4734                                .audio
4735                                .get_or_insert_default()
4736                                .legacy_audio_compatible
4737                        },
4738                    }),
4739                    metadata: None,
4740                    files: USER,
4741                }),
4742            ],
4743        },
4744        SettingsPage {
4745            title: "AI",
4746            items: vec![
4747                SettingsPageItem::SectionHeader("General"),
4748                SettingsPageItem::SettingItem(SettingItem {
4749                    title: "Disable AI",
4750                    description: "Whether to disable all AI features in Zed",
4751                    field: Box::new(SettingField {
4752                        pick: |settings_content| &settings_content.disable_ai,
4753                        pick_mut: |settings_content| &mut settings_content.disable_ai,
4754                    }),
4755                    metadata: None,
4756                    files: USER,
4757                }),
4758                SettingsPageItem::SectionHeader("Agent Configuration"),
4759                SettingsPageItem::SettingItem(SettingItem {
4760                    title: "Always Allow Tool Actions",
4761                    description: "When enabled, the agent can run potentially destructive actions without asking for your confirmation. This setting has no effect on external agents.",
4762                    field: Box::new(SettingField {
4763                        pick: |settings_content| {
4764                            if let Some(agent) = &settings_content.agent {
4765                                &agent.always_allow_tool_actions
4766                            } else {
4767                                &None
4768                            }
4769                        },
4770                        pick_mut: |settings_content| {
4771                            &mut settings_content
4772                                .agent
4773                                .get_or_insert_default()
4774                                .always_allow_tool_actions
4775                        },
4776                    }),
4777                    metadata: None,
4778                    files: USER,
4779                }),
4780                SettingsPageItem::SettingItem(SettingItem {
4781                    title: "Single File Review",
4782                    description: "When enabled, agent edits will also be displayed in single-file buffers for review",
4783                    field: Box::new(SettingField {
4784                        pick: |settings_content| {
4785                            if let Some(agent) = &settings_content.agent {
4786                                &agent.single_file_review
4787                            } else {
4788                                &None
4789                            }
4790                        },
4791                        pick_mut: |settings_content| {
4792                            &mut settings_content
4793                                .agent
4794                                .get_or_insert_default()
4795                                .single_file_review
4796                        },
4797                    }),
4798                    metadata: None,
4799                    files: USER,
4800                }),
4801                SettingsPageItem::SettingItem(SettingItem {
4802                    title: "Enable Feedback",
4803                    description: "Show voting thumbs up/down icon buttons for feedback on agent edits",
4804                    field: Box::new(SettingField {
4805                        pick: |settings_content| {
4806                            if let Some(agent) = &settings_content.agent {
4807                                &agent.enable_feedback
4808                            } else {
4809                                &None
4810                            }
4811                        },
4812                        pick_mut: |settings_content| {
4813                            &mut settings_content
4814                                .agent
4815                                .get_or_insert_default()
4816                                .enable_feedback
4817                        },
4818                    }),
4819                    metadata: None,
4820                    files: USER,
4821                }),
4822                SettingsPageItem::SettingItem(SettingItem {
4823                    title: "Notify When Agent Waiting",
4824                    description: "Where to show notifications when the agent has completed its response or needs confirmation before running a tool action",
4825                    field: Box::new(SettingField {
4826                        pick: |settings_content| {
4827                            if let Some(agent) = &settings_content.agent {
4828                                &agent.notify_when_agent_waiting
4829                            } else {
4830                                &None
4831                            }
4832                        },
4833                        pick_mut: |settings_content| {
4834                            &mut settings_content
4835                                .agent
4836                                .get_or_insert_default()
4837                                .notify_when_agent_waiting
4838                        },
4839                    }),
4840                    metadata: None,
4841                    files: USER,
4842                }),
4843                SettingsPageItem::SettingItem(SettingItem {
4844                    title: "Play Sound When Agent Done",
4845                    description: "Whether to play a sound when the agent has either completed its response, or needs user input",
4846                    field: Box::new(SettingField {
4847                        pick: |settings_content| {
4848                            if let Some(agent) = &settings_content.agent {
4849                                &agent.play_sound_when_agent_done
4850                            } else {
4851                                &None
4852                            }
4853                        },
4854                        pick_mut: |settings_content| {
4855                            &mut settings_content
4856                                .agent
4857                                .get_or_insert_default()
4858                                .play_sound_when_agent_done
4859                        },
4860                    }),
4861                    metadata: None,
4862                    files: USER,
4863                }),
4864                SettingsPageItem::SettingItem(SettingItem {
4865                    title: "Expand Edit Card",
4866                    description: "Whether to have edit cards in the agent panel expanded, showing a preview of the diff",
4867                    field: Box::new(SettingField {
4868                        pick: |settings_content| {
4869                            if let Some(agent) = &settings_content.agent {
4870                                &agent.expand_edit_card
4871                            } else {
4872                                &None
4873                            }
4874                        },
4875                        pick_mut: |settings_content| {
4876                            &mut settings_content
4877                                .agent
4878                                .get_or_insert_default()
4879                                .expand_edit_card
4880                        },
4881                    }),
4882                    metadata: None,
4883                    files: USER,
4884                }),
4885                SettingsPageItem::SettingItem(SettingItem {
4886                    title: "Expand Terminal Card",
4887                    description: "Whether to have terminal cards in the agent panel expanded, showing the whole command output",
4888                    field: Box::new(SettingField {
4889                        pick: |settings_content| {
4890                            if let Some(agent) = &settings_content.agent {
4891                                &agent.expand_terminal_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_terminal_card
4901                        },
4902                    }),
4903                    metadata: None,
4904                    files: USER,
4905                }),
4906                SettingsPageItem::SettingItem(SettingItem {
4907                    title: "Use Modifier To Send",
4908                    description: "Whether to always use cmd-enter (or ctrl-enter on Linux or Windows) to send messages",
4909                    field: Box::new(SettingField {
4910                        pick: |settings_content| {
4911                            if let Some(agent) = &settings_content.agent {
4912                                &agent.use_modifier_to_send
4913                            } else {
4914                                &None
4915                            }
4916                        },
4917                        pick_mut: |settings_content| {
4918                            &mut settings_content
4919                                .agent
4920                                .get_or_insert_default()
4921                                .use_modifier_to_send
4922                        },
4923                    }),
4924                    metadata: None,
4925                    files: USER,
4926                }),
4927                SettingsPageItem::SettingItem(SettingItem {
4928                    title: "Message Editor Min Lines",
4929                    description: "Minimum number of lines to display in the agent message editor",
4930                    field: Box::new(SettingField {
4931                        pick: |settings_content| {
4932                            if let Some(agent) = &settings_content.agent {
4933                                &agent.message_editor_min_lines
4934                            } else {
4935                                &None
4936                            }
4937                        },
4938                        pick_mut: |settings_content| {
4939                            &mut settings_content
4940                                .agent
4941                                .get_or_insert_default()
4942                                .message_editor_min_lines
4943                        },
4944                    }),
4945                    metadata: None,
4946                    files: USER,
4947                }),
4948            ],
4949        },
4950        SettingsPage {
4951            title: "Network",
4952            items: vec![
4953                SettingsPageItem::SectionHeader("Network"),
4954                // todo(settings_ui): Proxy needs a default
4955                SettingsPageItem::SettingItem(SettingItem {
4956                    title: "Proxy",
4957                    description: "The proxy to use for network requests",
4958                    field: Box::new(
4959                        SettingField {
4960                            pick: |settings_content| &settings_content.proxy,
4961                            pick_mut: |settings_content| &mut settings_content.proxy,
4962                        }
4963                        .unimplemented(),
4964                    ),
4965                    metadata: Some(Box::new(SettingsFieldMetadata {
4966                        placeholder: Some("socks5h://localhost:10808"),
4967                        ..Default::default()
4968                    })),
4969                    files: USER,
4970                }),
4971                SettingsPageItem::SettingItem(SettingItem {
4972                    title: "Server URL",
4973                    description: "The URL of the Zed server to connect to",
4974                    field: Box::new(SettingField {
4975                        pick: |settings_content| &settings_content.server_url,
4976                        pick_mut: |settings_content| &mut settings_content.server_url,
4977                    }),
4978                    metadata: Some(Box::new(SettingsFieldMetadata {
4979                        placeholder: Some("https://zed.dev"),
4980                        ..Default::default()
4981                    })),
4982                    files: USER,
4983                }),
4984            ],
4985        },
4986    ]
4987}
4988
4989const LANGUAGES_SECTION_HEADER: &'static str = "Languages";
4990
4991fn current_language() -> Option<SharedString> {
4992    sub_page_stack().iter().find_map(|page| {
4993        (page.section_header == LANGUAGES_SECTION_HEADER).then(|| page.link.title.clone())
4994    })
4995}
4996
4997fn language_settings_field<T>(
4998    settings_content: &SettingsContent,
4999    get: fn(&LanguageSettingsContent) -> &Option<T>,
5000) -> &Option<T> {
5001    let all_languages = &settings_content.project.all_languages;
5002    if let Some(current_language_name) = current_language() {
5003        if let Some(current_language) = all_languages.languages.0.get(&current_language_name) {
5004            let value = get(current_language);
5005            if value.is_some() {
5006                return value;
5007            }
5008        }
5009    }
5010    let default_value = get(&all_languages.defaults);
5011    return default_value;
5012}
5013
5014fn language_settings_field_mut<T>(
5015    settings_content: &mut SettingsContent,
5016    get: fn(&mut LanguageSettingsContent) -> &mut Option<T>,
5017) -> &mut Option<T> {
5018    let all_languages = &mut settings_content.project.all_languages;
5019    let language_content = if let Some(current_language) = current_language() {
5020        all_languages
5021            .languages
5022            .0
5023            .entry(current_language)
5024            .or_default()
5025    } else {
5026        &mut all_languages.defaults
5027    };
5028    return get(language_content);
5029}
5030
5031fn language_settings_data() -> Vec<SettingsPageItem> {
5032    let mut items = vec![
5033        SettingsPageItem::SectionHeader("Indentation"),
5034        SettingsPageItem::SettingItem(SettingItem {
5035            title: "Tab Size",
5036            description: "How many columns a tab should occupy",
5037            field: Box::new(SettingField {
5038                pick: |settings_content| {
5039                    language_settings_field(settings_content, |language| &language.tab_size)
5040                },
5041                pick_mut: |settings_content| {
5042                    language_settings_field_mut(settings_content, |language| &mut language.tab_size)
5043                },
5044            }),
5045            metadata: None,
5046            files: USER | LOCAL,
5047        }),
5048        SettingsPageItem::SettingItem(SettingItem {
5049            title: "Hard Tabs",
5050            description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
5051            field: Box::new(SettingField {
5052                pick: |settings_content| {
5053                    language_settings_field(settings_content, |language| &language.hard_tabs)
5054                },
5055                pick_mut: |settings_content| {
5056                    language_settings_field_mut(settings_content, |language| {
5057                        &mut language.hard_tabs
5058                    })
5059                },
5060            }),
5061            metadata: None,
5062            files: USER | LOCAL,
5063        }),
5064        SettingsPageItem::SettingItem(SettingItem {
5065            title: "Auto Indent",
5066            description: "Whether indentation should be adjusted based on the context whilst typing",
5067            field: Box::new(SettingField {
5068                pick: |settings_content| {
5069                    language_settings_field(settings_content, |language| &language.auto_indent)
5070                },
5071                pick_mut: |settings_content| {
5072                    language_settings_field_mut(settings_content, |language| {
5073                        &mut language.auto_indent
5074                    })
5075                },
5076            }),
5077            metadata: None,
5078            files: USER | LOCAL,
5079        }),
5080        SettingsPageItem::SettingItem(SettingItem {
5081            title: "Auto Indent On Paste",
5082            description: "Whether indentation of pasted content should be adjusted based on the context",
5083            field: Box::new(SettingField {
5084                pick: |settings_content| {
5085                    language_settings_field(settings_content, |language| {
5086                        &language.auto_indent_on_paste
5087                    })
5088                },
5089                pick_mut: |settings_content| {
5090                    language_settings_field_mut(settings_content, |language| {
5091                        &mut language.auto_indent_on_paste
5092                    })
5093                },
5094            }),
5095            metadata: None,
5096            files: USER | LOCAL,
5097        }),
5098        SettingsPageItem::SectionHeader("Wrapping"),
5099        SettingsPageItem::SettingItem(SettingItem {
5100            title: "Soft Wrap",
5101            description: "How to soft-wrap long lines of text",
5102            field: Box::new(SettingField {
5103                pick: |settings_content| {
5104                    language_settings_field(settings_content, |language| &language.soft_wrap)
5105                },
5106                pick_mut: |settings_content| {
5107                    language_settings_field_mut(settings_content, |language| {
5108                        &mut language.soft_wrap
5109                    })
5110                },
5111            }),
5112            metadata: None,
5113            files: USER | LOCAL,
5114        }),
5115        SettingsPageItem::SettingItem(SettingItem {
5116            title: "Show Wrap Guides",
5117            description: "Show wrap guides in the editor",
5118            field: Box::new(SettingField {
5119                pick: |settings_content| {
5120                    language_settings_field(settings_content, |language| &language.show_wrap_guides)
5121                },
5122                pick_mut: |settings_content| {
5123                    language_settings_field_mut(settings_content, |language| {
5124                        &mut language.show_wrap_guides
5125                    })
5126                },
5127            }),
5128            metadata: None,
5129            files: USER | LOCAL,
5130        }),
5131        SettingsPageItem::SettingItem(SettingItem {
5132            title: "Preferred Line Length",
5133            description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
5134            field: Box::new(SettingField {
5135                pick: |settings_content| {
5136                    language_settings_field(settings_content, |language| {
5137                        &language.preferred_line_length
5138                    })
5139                },
5140                pick_mut: |settings_content| {
5141                    language_settings_field_mut(settings_content, |language| {
5142                        &mut language.preferred_line_length
5143                    })
5144                },
5145            }),
5146            metadata: None,
5147            files: USER | LOCAL,
5148        }),
5149        SettingsPageItem::SettingItem(SettingItem {
5150            title: "Wrap Guides",
5151            description: "Character counts at which to show wrap guides in the editor",
5152            field: Box::new(
5153                SettingField {
5154                    pick: |settings_content| {
5155                        language_settings_field(settings_content, |language| &language.wrap_guides)
5156                    },
5157                    pick_mut: |settings_content| {
5158                        language_settings_field_mut(settings_content, |language| {
5159                            &mut language.wrap_guides
5160                        })
5161                    },
5162                }
5163                .unimplemented(),
5164            ),
5165            metadata: None,
5166            files: USER | LOCAL,
5167        }),
5168        SettingsPageItem::SettingItem(SettingItem {
5169            title: "Allow Rewrap",
5170            description: "Controls where the `editor::Rewrap` action is allowed for this language",
5171            field: Box::new(SettingField {
5172                pick: |settings_content| {
5173                    language_settings_field(settings_content, |language| &language.allow_rewrap)
5174                },
5175                pick_mut: |settings_content| {
5176                    language_settings_field_mut(settings_content, |language| {
5177                        &mut language.allow_rewrap
5178                    })
5179                },
5180            }),
5181            metadata: None,
5182            files: USER | LOCAL,
5183        }),
5184        SettingsPageItem::SectionHeader("Indent Guides"),
5185        SettingsPageItem::SettingItem(SettingItem {
5186            title: "Enabled",
5187            description: "Display indent guides in the editor",
5188            field: Box::new(SettingField {
5189                pick: |settings_content| {
5190                    language_settings_field(settings_content, |language| {
5191                        if let Some(indent_guides) = &language.indent_guides {
5192                            &indent_guides.enabled
5193                        } else {
5194                            &None
5195                        }
5196                    })
5197                },
5198                pick_mut: |settings_content| {
5199                    language_settings_field_mut(settings_content, |language| {
5200                        &mut language.indent_guides.get_or_insert_default().enabled
5201                    })
5202                },
5203            }),
5204            metadata: None,
5205            files: USER | LOCAL,
5206        }),
5207        SettingsPageItem::SettingItem(SettingItem {
5208            title: "Line Width",
5209            description: "The width of the indent guides in pixels, between 1 and 10",
5210            field: Box::new(SettingField {
5211                pick: |settings_content| {
5212                    language_settings_field(settings_content, |language| {
5213                        if let Some(indent_guides) = &language.indent_guides {
5214                            &indent_guides.line_width
5215                        } else {
5216                            &None
5217                        }
5218                    })
5219                },
5220                pick_mut: |settings_content| {
5221                    language_settings_field_mut(settings_content, |language| {
5222                        &mut language.indent_guides.get_or_insert_default().line_width
5223                    })
5224                },
5225            }),
5226            metadata: None,
5227            files: USER | LOCAL,
5228        }),
5229        SettingsPageItem::SettingItem(SettingItem {
5230            title: "Active Line Width",
5231            description: "The width of the active indent guide in pixels, between 1 and 10",
5232            field: Box::new(SettingField {
5233                pick: |settings_content| {
5234                    language_settings_field(settings_content, |language| {
5235                        if let Some(indent_guides) = &language.indent_guides {
5236                            &indent_guides.active_line_width
5237                        } else {
5238                            &None
5239                        }
5240                    })
5241                },
5242                pick_mut: |settings_content| {
5243                    language_settings_field_mut(settings_content, |language| {
5244                        &mut language
5245                            .indent_guides
5246                            .get_or_insert_default()
5247                            .active_line_width
5248                    })
5249                },
5250            }),
5251            metadata: None,
5252            files: USER | LOCAL,
5253        }),
5254        SettingsPageItem::SettingItem(SettingItem {
5255            title: "Coloring",
5256            description: "Determines how indent guides are colored",
5257            field: Box::new(SettingField {
5258                pick: |settings_content| {
5259                    language_settings_field(settings_content, |language| {
5260                        if let Some(indent_guides) = &language.indent_guides {
5261                            &indent_guides.coloring
5262                        } else {
5263                            &None
5264                        }
5265                    })
5266                },
5267                pick_mut: |settings_content| {
5268                    language_settings_field_mut(settings_content, |language| {
5269                        &mut language.indent_guides.get_or_insert_default().coloring
5270                    })
5271                },
5272            }),
5273            metadata: None,
5274            files: USER | LOCAL,
5275        }),
5276        SettingsPageItem::SettingItem(SettingItem {
5277            title: "Background Coloring",
5278            description: "Determines how indent guide backgrounds are colored",
5279            field: Box::new(SettingField {
5280                pick: |settings_content| {
5281                    language_settings_field(settings_content, |language| {
5282                        if let Some(indent_guides) = &language.indent_guides {
5283                            &indent_guides.background_coloring
5284                        } else {
5285                            &None
5286                        }
5287                    })
5288                },
5289                pick_mut: |settings_content| {
5290                    language_settings_field_mut(settings_content, |language| {
5291                        &mut language
5292                            .indent_guides
5293                            .get_or_insert_default()
5294                            .background_coloring
5295                    })
5296                },
5297            }),
5298            metadata: None,
5299            files: USER | LOCAL,
5300        }),
5301        SettingsPageItem::SectionHeader("Formatting"),
5302        SettingsPageItem::SettingItem(SettingItem {
5303            title: "Format On Save",
5304            description: "Whether or not to perform a buffer format before saving",
5305            field: Box::new(
5306                // TODO(settings_ui): this setting should just be a bool
5307                SettingField {
5308                    pick: |settings_content| {
5309                        language_settings_field(settings_content, |language| {
5310                            &language.format_on_save
5311                        })
5312                    },
5313                    pick_mut: |settings_content| {
5314                        language_settings_field_mut(settings_content, |language| {
5315                            &mut language.format_on_save
5316                        })
5317                    },
5318                },
5319            ),
5320            metadata: None,
5321            files: USER | LOCAL,
5322        }),
5323        SettingsPageItem::SettingItem(SettingItem {
5324            title: "Remove Trailing Whitespace On Save",
5325            description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
5326            field: Box::new(SettingField {
5327                pick: |settings_content| {
5328                    language_settings_field(settings_content, |language| {
5329                        &language.remove_trailing_whitespace_on_save
5330                    })
5331                },
5332                pick_mut: |settings_content| {
5333                    language_settings_field_mut(settings_content, |language| {
5334                        &mut language.remove_trailing_whitespace_on_save
5335                    })
5336                },
5337            }),
5338            metadata: None,
5339            files: USER | LOCAL,
5340        }),
5341        SettingsPageItem::SettingItem(SettingItem {
5342            title: "Ensure Final Newline On Save",
5343            description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
5344            field: Box::new(SettingField {
5345                pick: |settings_content| {
5346                    language_settings_field(settings_content, |language| {
5347                        &language.ensure_final_newline_on_save
5348                    })
5349                },
5350                pick_mut: |settings_content| {
5351                    language_settings_field_mut(settings_content, |language| {
5352                        &mut language.ensure_final_newline_on_save
5353                    })
5354                },
5355            }),
5356            metadata: None,
5357            files: USER | LOCAL,
5358        }),
5359        SettingsPageItem::SettingItem(SettingItem {
5360            title: "Formatter",
5361            description: "How to perform a buffer format",
5362            field: Box::new(
5363                SettingField {
5364                    pick: |settings_content| {
5365                        language_settings_field(settings_content, |language| &language.formatter)
5366                    },
5367                    pick_mut: |settings_content| {
5368                        language_settings_field_mut(settings_content, |language| {
5369                            &mut language.formatter
5370                        })
5371                    },
5372                }
5373                .unimplemented(),
5374            ),
5375            metadata: None,
5376            files: USER | LOCAL,
5377        }),
5378        SettingsPageItem::SettingItem(SettingItem {
5379            title: "Use On Type Format",
5380            description: "Whether to use additional LSP queries to format (and amend) the code after every \"trigger\" symbol input, defined by LSP server capabilities",
5381            field: Box::new(SettingField {
5382                pick: |settings_content| {
5383                    language_settings_field(settings_content, |language| {
5384                        &language.use_on_type_format
5385                    })
5386                },
5387                pick_mut: |settings_content| {
5388                    language_settings_field_mut(settings_content, |language| {
5389                        &mut language.use_on_type_format
5390                    })
5391                },
5392            }),
5393            metadata: None,
5394            files: USER | LOCAL,
5395        }),
5396        SettingsPageItem::SectionHeader("Autoclose"),
5397        SettingsPageItem::SettingItem(SettingItem {
5398            title: "Use Autoclose",
5399            description: "Whether to automatically type closing characters for you. For example, when you type (, Zed will automatically add a closing ) at the correct position",
5400            field: Box::new(SettingField {
5401                pick: |settings_content| {
5402                    language_settings_field(settings_content, |language| &language.use_autoclose)
5403                },
5404                pick_mut: |settings_content| {
5405                    language_settings_field_mut(settings_content, |language| {
5406                        &mut language.use_autoclose
5407                    })
5408                },
5409            }),
5410            metadata: None,
5411            files: USER | LOCAL,
5412        }),
5413        SettingsPageItem::SettingItem(SettingItem {
5414            title: "Use Auto Surround",
5415            description: "Whether to automatically surround text with characters for you. For example, when you select text and type (, Zed will automatically surround text with ()",
5416            field: Box::new(SettingField {
5417                pick: |settings_content| {
5418                    language_settings_field(settings_content, |language| {
5419                        &language.use_auto_surround
5420                    })
5421                },
5422                pick_mut: |settings_content| {
5423                    language_settings_field_mut(settings_content, |language| {
5424                        &mut language.use_auto_surround
5425                    })
5426                },
5427            }),
5428            metadata: None,
5429            files: USER | LOCAL,
5430        }),
5431        SettingsPageItem::SettingItem(SettingItem {
5432            title: "Always Treat Brackets As Autoclosed",
5433            description: "Controls whether the closing characters are always skipped over and auto-removed no matter how they were inserted",
5434            field: Box::new(SettingField {
5435                pick: |settings_content| {
5436                    language_settings_field(settings_content, |language| {
5437                        &language.always_treat_brackets_as_autoclosed
5438                    })
5439                },
5440                pick_mut: |settings_content| {
5441                    language_settings_field_mut(settings_content, |language| {
5442                        &mut language.always_treat_brackets_as_autoclosed
5443                    })
5444                },
5445            }),
5446            metadata: None,
5447            files: USER | LOCAL,
5448        }),
5449        SettingsPageItem::SettingItem(SettingItem {
5450            title: "Jsx Tag Auto Close",
5451            description: "Whether to automatically close JSX tags",
5452            field: Box::new(SettingField {
5453                // TODO(settings_ui): this setting should just be a bool
5454                pick: |settings_content| {
5455                    language_settings_field(settings_content, |language| {
5456                        match language.jsx_tag_auto_close.as_ref() {
5457                            Some(s) => &s.enabled,
5458                            None => &None,
5459                        }
5460                    })
5461                },
5462                pick_mut: |settings_content| {
5463                    language_settings_field_mut(settings_content, |language| {
5464                        &mut language.jsx_tag_auto_close.get_or_insert_default().enabled
5465                    })
5466                },
5467            }),
5468            metadata: None,
5469            files: USER | LOCAL,
5470        }),
5471        SettingsPageItem::SectionHeader("Edit Predictions"),
5472        SettingsPageItem::SettingItem(SettingItem {
5473            title: "Show Edit Predictions",
5474            description: "Controls whether edit predictions are shown immediately (true) or manually by triggering `editor::ShowEditPrediction` (false)",
5475            field: Box::new(SettingField {
5476                pick: |settings_content| {
5477                    language_settings_field(settings_content, |language| {
5478                        &language.show_edit_predictions
5479                    })
5480                },
5481                pick_mut: |settings_content| {
5482                    language_settings_field_mut(settings_content, |language| {
5483                        &mut language.show_edit_predictions
5484                    })
5485                },
5486            }),
5487            metadata: None,
5488            files: USER | LOCAL,
5489        }),
5490        SettingsPageItem::SettingItem(SettingItem {
5491            title: "Edit Predictions Disabled In",
5492            description: "Controls whether edit predictions are shown in the given language scopes",
5493            field: Box::new(
5494                SettingField {
5495                    pick: |settings_content| {
5496                        language_settings_field(settings_content, |language| {
5497                            &language.edit_predictions_disabled_in
5498                        })
5499                    },
5500                    pick_mut: |settings_content| {
5501                        language_settings_field_mut(settings_content, |language| {
5502                            &mut language.edit_predictions_disabled_in
5503                        })
5504                    },
5505                }
5506                .unimplemented(),
5507            ),
5508            metadata: None,
5509            files: USER | LOCAL,
5510        }),
5511        SettingsPageItem::SectionHeader("Whitespace"),
5512        SettingsPageItem::SettingItem(SettingItem {
5513            title: "Show Whitespaces",
5514            description: "Whether to show tabs and spaces in the editor",
5515            field: Box::new(SettingField {
5516                pick: |settings_content| {
5517                    language_settings_field(settings_content, |language| &language.show_whitespaces)
5518                },
5519                pick_mut: |settings_content| {
5520                    language_settings_field_mut(settings_content, |language| {
5521                        &mut language.show_whitespaces
5522                    })
5523                },
5524            }),
5525            metadata: None,
5526            files: USER | LOCAL,
5527        }),
5528        SettingsPageItem::SettingItem(SettingItem {
5529            title: "Space Whitespace Indicator",
5530            description: "Visible character used to render space characters when show_whitespaces is enabled (default: \"\")",
5531            field: Box::new(
5532                SettingField {
5533                    pick: |settings_content| {
5534                        language_settings_field(settings_content, |language| {
5535                            if let Some(whitespace_map) = &language.whitespace_map {
5536                                &whitespace_map.space
5537                            } else {
5538                                &None
5539                            }
5540                        })
5541                    },
5542                    pick_mut: |settings_content| {
5543                        language_settings_field_mut(settings_content, |language| {
5544                            &mut language.whitespace_map.get_or_insert_default().space
5545                        })
5546                    },
5547                }
5548                .unimplemented(),
5549            ),
5550            metadata: None,
5551            files: USER | LOCAL,
5552        }),
5553        SettingsPageItem::SettingItem(SettingItem {
5554            title: "Tab Whitespace Indicator",
5555            description: "Visible character used to render tab characters when show_whitespaces is enabled (default: \"\")",
5556            field: Box::new(
5557                SettingField {
5558                    pick: |settings_content| {
5559                        language_settings_field(settings_content, |language| {
5560                            if let Some(whitespace_map) = &language.whitespace_map {
5561                                &whitespace_map.tab
5562                            } else {
5563                                &None
5564                            }
5565                        })
5566                    },
5567                    pick_mut: |settings_content| {
5568                        language_settings_field_mut(settings_content, |language| {
5569                            &mut language.whitespace_map.get_or_insert_default().tab
5570                        })
5571                    },
5572                }
5573                .unimplemented(),
5574            ),
5575            metadata: None,
5576            files: USER | LOCAL,
5577        }),
5578        SettingsPageItem::SectionHeader("Completions"),
5579        SettingsPageItem::SettingItem(SettingItem {
5580            title: "Show Completions On Input",
5581            description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
5582            field: Box::new(SettingField {
5583                pick: |settings_content| {
5584                    language_settings_field(settings_content, |language| {
5585                        &language.show_completions_on_input
5586                    })
5587                },
5588                pick_mut: |settings_content| {
5589                    language_settings_field_mut(settings_content, |language| {
5590                        &mut language.show_completions_on_input
5591                    })
5592                },
5593            }),
5594            metadata: None,
5595            files: USER | LOCAL,
5596        }),
5597        SettingsPageItem::SettingItem(SettingItem {
5598            title: "Show Completion Documentation",
5599            description: "Whether to display inline and alongside documentation for items in the completions menu",
5600            field: Box::new(SettingField {
5601                pick: |settings_content| {
5602                    language_settings_field(settings_content, |language| {
5603                        &language.show_completion_documentation
5604                    })
5605                },
5606                pick_mut: |settings_content| {
5607                    language_settings_field_mut(settings_content, |language| {
5608                        &mut language.show_completion_documentation
5609                    })
5610                },
5611            }),
5612            metadata: None,
5613            files: USER | LOCAL,
5614        }),
5615        SettingsPageItem::SettingItem(SettingItem {
5616            title: "Words",
5617            description: "Controls how words are completed",
5618            field: Box::new(SettingField {
5619                pick: |settings_content| {
5620                    language_settings_field(settings_content, |language| {
5621                        if let Some(completions) = &language.completions {
5622                            &completions.words
5623                        } else {
5624                            &None
5625                        }
5626                    })
5627                },
5628                pick_mut: |settings_content| {
5629                    language_settings_field_mut(settings_content, |language| {
5630                        &mut language.completions.get_or_insert_default().words
5631                    })
5632                },
5633            }),
5634            metadata: None,
5635            files: USER | LOCAL,
5636        }),
5637        SettingsPageItem::SettingItem(SettingItem {
5638            title: "Words Min Length",
5639            description: "How many characters has to be in the completions query to automatically show the words-based completions",
5640            field: Box::new(SettingField {
5641                pick: |settings_content| {
5642                    language_settings_field(settings_content, |language| {
5643                        if let Some(completions) = &language.completions {
5644                            &completions.words_min_length
5645                        } else {
5646                            &None
5647                        }
5648                    })
5649                },
5650                pick_mut: |settings_content| {
5651                    language_settings_field_mut(settings_content, |language| {
5652                        &mut language
5653                            .completions
5654                            .get_or_insert_default()
5655                            .words_min_length
5656                    })
5657                },
5658            }),
5659            metadata: None,
5660            files: USER | LOCAL,
5661        }),
5662        SettingsPageItem::SectionHeader("Inlay Hints"),
5663        SettingsPageItem::SettingItem(SettingItem {
5664            title: "Enabled",
5665            description: "Global switch to toggle hints on and off",
5666            field: Box::new(SettingField {
5667                pick: |settings_content| {
5668                    language_settings_field(settings_content, |language| {
5669                        if let Some(inlay_hints) = &language.inlay_hints {
5670                            &inlay_hints.enabled
5671                        } else {
5672                            &None
5673                        }
5674                    })
5675                },
5676                pick_mut: |settings_content| {
5677                    language_settings_field_mut(settings_content, |language| {
5678                        &mut language.inlay_hints.get_or_insert_default().enabled
5679                    })
5680                },
5681            }),
5682            metadata: None,
5683            files: USER | LOCAL,
5684        }),
5685        SettingsPageItem::SettingItem(SettingItem {
5686            title: "Show Value Hints",
5687            description: "Global switch to toggle inline values on and off when debugging",
5688            field: Box::new(SettingField {
5689                pick: |settings_content| {
5690                    language_settings_field(settings_content, |language| {
5691                        if let Some(inlay_hints) = &language.inlay_hints {
5692                            &inlay_hints.show_value_hints
5693                        } else {
5694                            &None
5695                        }
5696                    })
5697                },
5698                pick_mut: |settings_content| {
5699                    language_settings_field_mut(settings_content, |language| {
5700                        &mut language
5701                            .inlay_hints
5702                            .get_or_insert_default()
5703                            .show_value_hints
5704                    })
5705                },
5706            }),
5707            metadata: None,
5708            files: USER | LOCAL,
5709        }),
5710        SettingsPageItem::SettingItem(SettingItem {
5711            title: "Show Type Hints",
5712            description: "Whether type hints should be shown",
5713            field: Box::new(SettingField {
5714                pick: |settings_content| {
5715                    language_settings_field(settings_content, |language| {
5716                        if let Some(inlay_hints) = &language.inlay_hints {
5717                            &inlay_hints.show_type_hints
5718                        } else {
5719                            &None
5720                        }
5721                    })
5722                },
5723                pick_mut: |settings_content| {
5724                    language_settings_field_mut(settings_content, |language| {
5725                        &mut language.inlay_hints.get_or_insert_default().show_type_hints
5726                    })
5727                },
5728            }),
5729            metadata: None,
5730            files: USER | LOCAL,
5731        }),
5732        SettingsPageItem::SettingItem(SettingItem {
5733            title: "Show Parameter Hints",
5734            description: "Whether parameter hints should be shown",
5735            field: Box::new(SettingField {
5736                pick: |settings_content| {
5737                    language_settings_field(settings_content, |language| {
5738                        if let Some(inlay_hints) = &language.inlay_hints {
5739                            &inlay_hints.show_parameter_hints
5740                        } else {
5741                            &None
5742                        }
5743                    })
5744                },
5745                pick_mut: |settings_content| {
5746                    language_settings_field_mut(settings_content, |language| {
5747                        &mut language
5748                            .inlay_hints
5749                            .get_or_insert_default()
5750                            .show_parameter_hints
5751                    })
5752                },
5753            }),
5754            metadata: None,
5755            files: USER | LOCAL,
5756        }),
5757        SettingsPageItem::SettingItem(SettingItem {
5758            title: "Show Other Hints",
5759            description: "Whether other hints should be shown",
5760            field: Box::new(SettingField {
5761                pick: |settings_content| {
5762                    language_settings_field(settings_content, |language| {
5763                        if let Some(inlay_hints) = &language.inlay_hints {
5764                            &inlay_hints.show_other_hints
5765                        } else {
5766                            &None
5767                        }
5768                    })
5769                },
5770                pick_mut: |settings_content| {
5771                    language_settings_field_mut(settings_content, |language| {
5772                        &mut language
5773                            .inlay_hints
5774                            .get_or_insert_default()
5775                            .show_other_hints
5776                    })
5777                },
5778            }),
5779            metadata: None,
5780            files: USER | LOCAL,
5781        }),
5782        SettingsPageItem::SettingItem(SettingItem {
5783            title: "Show Background",
5784            description: "Show a background for inlay hints",
5785            field: Box::new(SettingField {
5786                pick: |settings_content| {
5787                    language_settings_field(settings_content, |language| {
5788                        if let Some(inlay_hints) = &language.inlay_hints {
5789                            &inlay_hints.show_background
5790                        } else {
5791                            &None
5792                        }
5793                    })
5794                },
5795                pick_mut: |settings_content| {
5796                    language_settings_field_mut(settings_content, |language| {
5797                        &mut language.inlay_hints.get_or_insert_default().show_background
5798                    })
5799                },
5800            }),
5801            metadata: None,
5802            files: USER | LOCAL,
5803        }),
5804        SettingsPageItem::SettingItem(SettingItem {
5805            title: "Edit Debounce Ms",
5806            description: "Whether or not to debounce inlay hints updates after buffer edits (set to 0 to disable debouncing)",
5807            field: Box::new(SettingField {
5808                pick: |settings_content| {
5809                    language_settings_field(settings_content, |language| {
5810                        if let Some(inlay_hints) = &language.inlay_hints {
5811                            &inlay_hints.edit_debounce_ms
5812                        } else {
5813                            &None
5814                        }
5815                    })
5816                },
5817                pick_mut: |settings_content| {
5818                    language_settings_field_mut(settings_content, |language| {
5819                        &mut language
5820                            .inlay_hints
5821                            .get_or_insert_default()
5822                            .edit_debounce_ms
5823                    })
5824                },
5825            }),
5826            metadata: None,
5827            files: USER | LOCAL,
5828        }),
5829        SettingsPageItem::SettingItem(SettingItem {
5830            title: "Scroll Debounce Ms",
5831            description: "Whether or not to debounce inlay hints updates after buffer scrolls (set to 0 to disable debouncing)",
5832            field: Box::new(SettingField {
5833                pick: |settings_content| {
5834                    language_settings_field(settings_content, |language| {
5835                        if let Some(inlay_hints) = &language.inlay_hints {
5836                            &inlay_hints.scroll_debounce_ms
5837                        } else {
5838                            &None
5839                        }
5840                    })
5841                },
5842                pick_mut: |settings_content| {
5843                    language_settings_field_mut(settings_content, |language| {
5844                        &mut language
5845                            .inlay_hints
5846                            .get_or_insert_default()
5847                            .scroll_debounce_ms
5848                    })
5849                },
5850            }),
5851            metadata: None,
5852            files: USER | LOCAL,
5853        }),
5854        SettingsPageItem::SettingItem(SettingItem {
5855            title: "Toggle On Modifiers Press",
5856            description: "Toggles inlay hints (hides or shows) when the user presses the modifiers specified",
5857            field: Box::new(
5858                SettingField {
5859                    pick: |settings_content| {
5860                        language_settings_field(settings_content, |language| {
5861                            if let Some(inlay_hints) = &language.inlay_hints {
5862                                &inlay_hints.toggle_on_modifiers_press
5863                            } else {
5864                                &None
5865                            }
5866                        })
5867                    },
5868                    pick_mut: |settings_content| {
5869                        language_settings_field_mut(settings_content, |language| {
5870                            &mut language
5871                                .inlay_hints
5872                                .get_or_insert_default()
5873                                .toggle_on_modifiers_press
5874                        })
5875                    },
5876                }
5877                .unimplemented(),
5878            ),
5879            metadata: None,
5880            files: USER | LOCAL,
5881        }),
5882    ];
5883    if current_language().is_none() {
5884        items.push(SettingsPageItem::SettingItem(SettingItem {
5885            title: "LSP Document Colors",
5886            description: "How to render LSP color previews in the editor",
5887            field: Box::new(SettingField {
5888                pick: |settings_content| &settings_content.editor.lsp_document_colors,
5889                pick_mut: |settings_content| &mut settings_content.editor.lsp_document_colors,
5890            }),
5891            metadata: None,
5892            files: USER,
5893        }))
5894    }
5895    items.extend([
5896        SettingsPageItem::SectionHeader("Tasks"),
5897        SettingsPageItem::SettingItem(SettingItem {
5898            title: "Enabled",
5899            description: "Whether tasks are enabled for this language",
5900            field: Box::new(SettingField {
5901                pick: |settings_content| {
5902                    language_settings_field(settings_content, |language| {
5903                        if let Some(tasks) = &language.tasks {
5904                            &tasks.enabled
5905                        } else {
5906                            &None
5907                        }
5908                    })
5909                },
5910                pick_mut: |settings_content| {
5911                    language_settings_field_mut(settings_content, |language| {
5912                        &mut language.tasks.get_or_insert_default().enabled
5913                    })
5914                },
5915            }),
5916            metadata: None,
5917            files: USER | LOCAL,
5918        }),
5919        SettingsPageItem::SettingItem(SettingItem {
5920            title: "Variables",
5921            description: "Extra task variables to set for a particular language",
5922            field: Box::new(
5923                SettingField {
5924                    pick: |settings_content| {
5925                        language_settings_field(settings_content, |language| {
5926                            if let Some(tasks) = &language.tasks {
5927                                &tasks.variables
5928                            } else {
5929                                &None
5930                            }
5931                        })
5932                    },
5933                    pick_mut: |settings_content| {
5934                        language_settings_field_mut(settings_content, |language| {
5935                            &mut language.tasks.get_or_insert_default().variables
5936                        })
5937                    },
5938                }
5939                .unimplemented(),
5940            ),
5941            metadata: None,
5942            files: USER | LOCAL,
5943        }),
5944        SettingsPageItem::SettingItem(SettingItem {
5945            title: "Prefer LSP",
5946            description: "Use LSP tasks over Zed language extension tasks",
5947            field: Box::new(SettingField {
5948                pick: |settings_content| {
5949                    language_settings_field(settings_content, |language| {
5950                        if let Some(tasks) = &language.tasks {
5951                            &tasks.prefer_lsp
5952                        } else {
5953                            &None
5954                        }
5955                    })
5956                },
5957                pick_mut: |settings_content| {
5958                    language_settings_field_mut(settings_content, |language| {
5959                        &mut language.tasks.get_or_insert_default().prefer_lsp
5960                    })
5961                },
5962            }),
5963            metadata: None,
5964            files: USER | LOCAL,
5965        }),
5966        SettingsPageItem::SectionHeader("Miscellaneous"),
5967        SettingsPageItem::SettingItem(SettingItem {
5968            title: "Debuggers",
5969            description: "Preferred debuggers for this language",
5970            field: Box::new(
5971                SettingField {
5972                    pick: |settings_content| {
5973                        language_settings_field(settings_content, |language| &language.debuggers)
5974                    },
5975                    pick_mut: |settings_content| {
5976                        language_settings_field_mut(settings_content, |language| {
5977                            &mut language.debuggers
5978                        })
5979                    },
5980                }
5981                .unimplemented(),
5982            ),
5983            metadata: None,
5984            files: USER | LOCAL,
5985        }),
5986        SettingsPageItem::SettingItem(SettingItem {
5987            title: "Middle Click Paste",
5988            description: "Enable middle-click paste on Linux",
5989            field: Box::new(SettingField {
5990                pick: |settings_content| &settings_content.editor.middle_click_paste,
5991                pick_mut: |settings_content| &mut settings_content.editor.middle_click_paste,
5992            }),
5993            metadata: None,
5994            files: USER,
5995        }),
5996        SettingsPageItem::SettingItem(SettingItem {
5997            title: "Extend Comment On Newline",
5998            description: "Whether to start a new line with a comment when a previous line is a comment as well",
5999            field: Box::new(SettingField {
6000                pick: |settings_content| {
6001                    language_settings_field(settings_content, |language| {
6002                        &language.extend_comment_on_newline
6003                    })
6004                },
6005                pick_mut: |settings_content| {
6006                    language_settings_field_mut(settings_content, |language| {
6007                        &mut language.extend_comment_on_newline
6008                    })
6009                },
6010            }),
6011            metadata: None,
6012            files: USER | LOCAL,
6013        }),
6014    ]);
6015
6016    if current_language().is_none() {
6017        items.extend([
6018            SettingsPageItem::SettingItem(SettingItem {
6019                title: "Image Viewer",
6020                description: "The unit for image file sizes",
6021                field: Box::new(SettingField {
6022                    pick: |settings_content| {
6023                        if let Some(image_viewer) = settings_content.image_viewer.as_ref() {
6024                            &image_viewer.unit
6025                        } else {
6026                            &None
6027                        }
6028                    },
6029                    pick_mut: |settings_content| {
6030                        &mut settings_content.image_viewer.get_or_insert_default().unit
6031                    },
6032                }),
6033                metadata: None,
6034                files: USER,
6035            }),
6036            SettingsPageItem::SettingItem(SettingItem {
6037                title: "Auto Replace Emoji Shortcode",
6038                description: "Whether to automatically replace emoji shortcodes with emoji characters",
6039                field: Box::new(SettingField {
6040                    pick: |settings_content| {
6041                        if let Some(message_editor) = settings_content.message_editor.as_ref() {
6042                            &message_editor.auto_replace_emoji_shortcode
6043                        } else {
6044                            &None
6045                        }
6046                    },
6047                    pick_mut: |settings_content| {
6048                        &mut settings_content.message_editor.get_or_insert_default().auto_replace_emoji_shortcode
6049                    },
6050                }),
6051                metadata: None,
6052                files: USER,
6053            }),
6054            SettingsPageItem::SettingItem(SettingItem {
6055                title: "Drop Size Target",
6056                description: "Relative size of the drop target in the editor that will open dropped file as a split pane",
6057                field: Box::new(SettingField {
6058                    pick: |settings_content| {
6059                        &settings_content.workspace.drop_target_size
6060                    },
6061                    pick_mut: |settings_content| {
6062                        &mut settings_content.workspace.drop_target_size
6063                    },
6064                }),
6065                metadata: None,
6066                files: USER,
6067            }),
6068        ]);
6069    }
6070    items
6071}
6072
6073/// LanguageSettings items that should be included in the "Languages & Tools" page
6074/// not the "Editor" page
6075fn non_editor_language_settings_data() -> Vec<SettingsPageItem> {
6076    vec![
6077        SettingsPageItem::SectionHeader("LSP"),
6078        SettingsPageItem::SettingItem(SettingItem {
6079            title: "Enable Language Server",
6080            description: "Whether to use language servers to provide code intelligence",
6081            field: Box::new(SettingField {
6082                pick: |settings_content| {
6083                    language_settings_field(settings_content, |language| {
6084                        &language.enable_language_server
6085                    })
6086                },
6087                pick_mut: |settings_content| {
6088                    language_settings_field_mut(settings_content, |language| {
6089                        &mut language.enable_language_server
6090                    })
6091                },
6092            }),
6093            metadata: None,
6094            files: USER | LOCAL,
6095        }),
6096        SettingsPageItem::SettingItem(SettingItem {
6097            title: "Language Servers",
6098            description: "The list of language servers to use (or disable) for this language",
6099            field: Box::new(
6100                SettingField {
6101                    pick: |settings_content| {
6102                        language_settings_field(settings_content, |language| {
6103                            &language.language_servers
6104                        })
6105                    },
6106                    pick_mut: |settings_content| {
6107                        language_settings_field_mut(settings_content, |language| {
6108                            &mut language.language_servers
6109                        })
6110                    },
6111                }
6112                .unimplemented(),
6113            ),
6114            metadata: None,
6115            files: USER | LOCAL,
6116        }),
6117        SettingsPageItem::SettingItem(SettingItem {
6118            title: "Linked Edits",
6119            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",
6120            field: Box::new(SettingField {
6121                pick: |settings_content| {
6122                    language_settings_field(settings_content, |language| &language.linked_edits)
6123                },
6124                pick_mut: |settings_content| {
6125                    language_settings_field_mut(settings_content, |language| {
6126                        &mut language.linked_edits
6127                    })
6128                },
6129            }),
6130            metadata: None,
6131            files: USER | LOCAL,
6132        }),
6133        SettingsPageItem::SettingItem(SettingItem {
6134            title: "Go To Definition Fallback",
6135            description: "Whether to follow-up empty go to definition responses from the language server",
6136            field: Box::new(SettingField {
6137                pick: |settings_content| &settings_content.editor.go_to_definition_fallback,
6138                pick_mut: |settings_content| &mut settings_content.editor.go_to_definition_fallback,
6139            }),
6140            metadata: None,
6141            files: USER,
6142        }),
6143        SettingsPageItem::SectionHeader("LSP Completions"),
6144        SettingsPageItem::SettingItem(SettingItem {
6145            title: "Enabled",
6146            description: "Whether to fetch LSP completions or not",
6147            field: Box::new(SettingField {
6148                pick: |settings_content| {
6149                    language_settings_field(settings_content, |language| {
6150                        if let Some(completions) = &language.completions {
6151                            &completions.lsp
6152                        } else {
6153                            &None
6154                        }
6155                    })
6156                },
6157                pick_mut: |settings_content| {
6158                    language_settings_field_mut(settings_content, |language| {
6159                        &mut language.completions.get_or_insert_default().lsp
6160                    })
6161                },
6162            }),
6163            metadata: None,
6164            files: USER | LOCAL,
6165        }),
6166        SettingsPageItem::SettingItem(SettingItem {
6167            title: "Fetch Timeout (milliseconds)",
6168            description: "When fetching LSP completions, determines how long to wait for a response of a particular server (set to 0 to wait indefinitely)",
6169            field: Box::new(SettingField {
6170                pick: |settings_content| {
6171                    language_settings_field(settings_content, |language| {
6172                        if let Some(completions) = &language.completions {
6173                            &completions.lsp_fetch_timeout_ms
6174                        } else {
6175                            &None
6176                        }
6177                    })
6178                },
6179                pick_mut: |settings_content| {
6180                    language_settings_field_mut(settings_content, |language| {
6181                        &mut language
6182                            .completions
6183                            .get_or_insert_default()
6184                            .lsp_fetch_timeout_ms
6185                    })
6186                },
6187            }),
6188            metadata: None,
6189            files: USER | LOCAL,
6190        }),
6191        SettingsPageItem::SettingItem(SettingItem {
6192            title: "Insert Mode",
6193            description: "Controls how LSP completions are inserted",
6194            field: Box::new(SettingField {
6195                pick: |settings_content| {
6196                    language_settings_field(settings_content, |language| {
6197                        if let Some(completions) = &language.completions {
6198                            &completions.lsp_insert_mode
6199                        } else {
6200                            &None
6201                        }
6202                    })
6203                },
6204                pick_mut: |settings_content| {
6205                    language_settings_field_mut(settings_content, |language| {
6206                        &mut language.completions.get_or_insert_default().lsp_insert_mode
6207                    })
6208                },
6209            }),
6210            metadata: None,
6211            files: USER | LOCAL,
6212        }),
6213        SettingsPageItem::SectionHeader("Debuggers"),
6214        SettingsPageItem::SettingItem(SettingItem {
6215            title: "Debuggers",
6216            description: "Preferred debuggers for this language",
6217            field: Box::new(
6218                SettingField {
6219                    pick: |settings_content| {
6220                        language_settings_field(settings_content, |language| &language.debuggers)
6221                    },
6222                    pick_mut: |settings_content| {
6223                        language_settings_field_mut(settings_content, |language| {
6224                            &mut language.debuggers
6225                        })
6226                    },
6227                }
6228                .unimplemented(),
6229            ),
6230            metadata: None,
6231            files: USER | LOCAL,
6232        }),
6233        SettingsPageItem::SectionHeader("Prettier"),
6234        SettingsPageItem::SettingItem(SettingItem {
6235            title: "Allowed",
6236            description: "Enables or disables formatting with Prettier for a given language",
6237            field: Box::new(SettingField {
6238                pick: |settings_content| {
6239                    language_settings_field(settings_content, |language| {
6240                        if let Some(prettier) = &language.prettier {
6241                            &prettier.allowed
6242                        } else {
6243                            &None
6244                        }
6245                    })
6246                },
6247                pick_mut: |settings_content| {
6248                    language_settings_field_mut(settings_content, |language| {
6249                        &mut language.prettier.get_or_insert_default().allowed
6250                    })
6251                },
6252            }),
6253            metadata: None,
6254            files: USER | LOCAL,
6255        }),
6256        SettingsPageItem::SettingItem(SettingItem {
6257            title: "Parser",
6258            description: "Forces Prettier integration to use a specific parser name when formatting files with the language",
6259            field: Box::new(SettingField {
6260                pick: |settings_content| {
6261                    language_settings_field(settings_content, |language| {
6262                        if let Some(prettier) = &language.prettier {
6263                            &prettier.parser
6264                        } else {
6265                            &None
6266                        }
6267                    })
6268                },
6269                pick_mut: |settings_content| {
6270                    language_settings_field_mut(settings_content, |language| {
6271                        &mut language.prettier.get_or_insert_default().parser
6272                    })
6273                },
6274            }),
6275            metadata: None,
6276            files: USER | LOCAL,
6277        }),
6278        SettingsPageItem::SettingItem(SettingItem {
6279            title: "Plugins",
6280            description: "Forces Prettier integration to use specific plugins when formatting files with the language",
6281            field: Box::new(
6282                SettingField {
6283                    pick: |settings_content| {
6284                        language_settings_field(settings_content, |language| {
6285                            if let Some(prettier) = &language.prettier {
6286                                &prettier.plugins
6287                            } else {
6288                                &None
6289                            }
6290                        })
6291                    },
6292                    pick_mut: |settings_content| {
6293                        language_settings_field_mut(settings_content, |language| {
6294                            &mut language.prettier.get_or_insert_default().plugins
6295                        })
6296                    },
6297                }
6298                .unimplemented(),
6299            ),
6300            metadata: None,
6301            files: USER | LOCAL,
6302        }),
6303        SettingsPageItem::SettingItem(SettingItem {
6304            title: "Options",
6305            description: "Default Prettier options, in the format as in package.json section for Prettier",
6306            field: Box::new(
6307                SettingField {
6308                    pick: |settings_content| {
6309                        language_settings_field(settings_content, |language| {
6310                            if let Some(prettier) = &language.prettier {
6311                                &prettier.options
6312                            } else {
6313                                &None
6314                            }
6315                        })
6316                    },
6317                    pick_mut: |settings_content| {
6318                        language_settings_field_mut(settings_content, |language| {
6319                            &mut language.prettier.get_or_insert_default().options
6320                        })
6321                    },
6322                }
6323                .unimplemented(),
6324            ),
6325            metadata: None,
6326            files: USER | LOCAL,
6327        }),
6328    ]
6329}