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