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