page_data.rs

   1use gpui::IntoElement;
   2use std::rc::Rc;
   3
   4use crate::{
   5    SettingField, SettingItem, SettingsFieldMetadata, SettingsPage, SettingsPageItem, SubPageLink,
   6};
   7
   8pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
   9    vec![
  10        SettingsPage {
  11            title: "General Page",
  12            items: vec![
  13                SettingsPageItem::SectionHeader("General"),
  14                SettingsPageItem::SettingItem(SettingItem {
  15                    title: "Confirm Quit",
  16                    description: "Whether to confirm before quitting Zed",
  17                    field: Box::new(SettingField {
  18                        pick: |settings_content| &settings_content.workspace.confirm_quit,
  19                        pick_mut: |settings_content| &mut settings_content.workspace.confirm_quit,
  20                    }),
  21                    metadata: None,
  22                }),
  23                SettingsPageItem::SettingItem(SettingItem {
  24                    title: "Restore On Startup",
  25                    description: "Whether to restore previous session when opening Zed",
  26                    field: Box::new(SettingField {
  27                        pick: |settings_content| &settings_content.workspace.restore_on_startup,
  28                        pick_mut: |settings_content| {
  29                            &mut settings_content.workspace.restore_on_startup
  30                        },
  31                    }),
  32                    metadata: None,
  33                }),
  34                SettingsPageItem::SettingItem(SettingItem {
  35                    title: "Restore File State",
  36                    description: "Whether to restore previous file state when reopening",
  37                    field: Box::new(SettingField {
  38                        pick: |settings_content| &settings_content.workspace.restore_on_file_reopen,
  39                        pick_mut: |settings_content| {
  40                            &mut settings_content.workspace.restore_on_file_reopen
  41                        },
  42                    }),
  43                    metadata: None,
  44                }),
  45                SettingsPageItem::SettingItem(SettingItem {
  46                    title: "Close on File Delete",
  47                    description: "Whether to automatically close files that have been deleted",
  48                    field: Box::new(SettingField {
  49                        pick: |settings_content| &settings_content.workspace.close_on_file_delete,
  50                        pick_mut: |settings_content| {
  51                            &mut settings_content.workspace.close_on_file_delete
  52                        },
  53                    }),
  54                    metadata: None,
  55                }),
  56                SettingsPageItem::SettingItem(SettingItem {
  57                    title: "When Closing With No Tabs",
  58                    description: "What to do when using 'close active item' with no tabs",
  59                    field: Box::new(SettingField {
  60                        pick: |settings_content| {
  61                            &settings_content.workspace.when_closing_with_no_tabs
  62                        },
  63                        pick_mut: |settings_content| {
  64                            &mut settings_content.workspace.when_closing_with_no_tabs
  65                        },
  66                    }),
  67                    metadata: None,
  68                }),
  69                SettingsPageItem::SettingItem(SettingItem {
  70                    title: "On Last Window Closed",
  71                    description: "What to do when the last window is closed",
  72                    field: Box::new(SettingField {
  73                        pick: |settings_content| &settings_content.workspace.on_last_window_closed,
  74                        pick_mut: |settings_content| {
  75                            &mut settings_content.workspace.on_last_window_closed
  76                        },
  77                    }),
  78                    metadata: None,
  79                }),
  80                SettingsPageItem::SettingItem(SettingItem {
  81                    title: "Use System Path Prompts",
  82                    description: "Whether to use system dialogs for Open and Save As",
  83                    field: Box::new(SettingField {
  84                        pick: |settings_content| {
  85                            &settings_content.workspace.use_system_path_prompts
  86                        },
  87                        pick_mut: |settings_content| {
  88                            &mut settings_content.workspace.use_system_path_prompts
  89                        },
  90                    }),
  91                    metadata: None,
  92                }),
  93                SettingsPageItem::SettingItem(SettingItem {
  94                    title: "Use System Prompts",
  95                    description: "Whether to use system prompts for confirmations",
  96                    field: Box::new(SettingField {
  97                        pick: |settings_content| &settings_content.workspace.use_system_prompts,
  98                        pick_mut: |settings_content| {
  99                            &mut settings_content.workspace.use_system_prompts
 100                        },
 101                    }),
 102                    metadata: None,
 103                }),
 104                SettingsPageItem::SectionHeader("Scoped Settings"),
 105                // todo(settings_ui): Implement another setting item type that just shows an edit in settings.json
 106                // SettingsPageItem::SettingItem(SettingItem {
 107                //     title: "Preview Channel",
 108                //     description: "Which settings should be activated only in Preview build of Zed",
 109                //     field: Box::new(SettingField {
 110                //         pick: |settings_content| &settings_content.workspace.use_system_prompts,
 111                //         pick_mut: |settings_content| {
 112                //             &mut settings_content.workspace.use_system_prompts
 113                //         },
 114                //     }),
 115                //     metadata: None,
 116                // }),
 117                // SettingsPageItem::SettingItem(SettingItem {
 118                //     title: "Settings Profiles",
 119                //     description: "Any number of settings profiles that are temporarily applied on top of your existing user settings.",
 120                //     field: Box::new(SettingField {
 121                //         pick: |settings_content| &settings_content.workspace.use_system_prompts,
 122                //         pick_mut: |settings_content| {
 123                //             &mut settings_content.workspace.use_system_prompts
 124                //         },
 125                //     }),
 126                //     metadata: None,
 127                // }),
 128                SettingsPageItem::SectionHeader("Privacy"),
 129                SettingsPageItem::SettingItem(SettingItem {
 130                    title: "Telemetry Diagnostics",
 131                    description: "Send debug info like crash reports.",
 132                    field: Box::new(SettingField {
 133                        pick: |settings_content| {
 134                            if let Some(telemetry) = &settings_content.telemetry {
 135                                &telemetry.diagnostics
 136                            } else {
 137                                &None
 138                            }
 139                        },
 140                        pick_mut: |settings_content| {
 141                            &mut settings_content
 142                                .telemetry
 143                                .get_or_insert_default()
 144                                .diagnostics
 145                        },
 146                    }),
 147                    metadata: None,
 148                }),
 149                SettingsPageItem::SettingItem(SettingItem {
 150                    title: "Telemetry Metrics",
 151                    description: "Send anonymized usage data like what languages you're using Zed with.",
 152                    field: Box::new(SettingField {
 153                        pick: |settings_content| {
 154                            if let Some(telemetry) = &settings_content.telemetry {
 155                                &telemetry.metrics
 156                            } else {
 157                                &None
 158                            }
 159                        },
 160                        pick_mut: |settings_content| {
 161                            &mut settings_content.telemetry.get_or_insert_default().metrics
 162                        },
 163                    }),
 164                    metadata: None,
 165                }),
 166            ],
 167        },
 168        SettingsPage {
 169            title: "Appearance & Behavior",
 170            items: vec![
 171                SettingsPageItem::SectionHeader("Theme"),
 172                // todo(settings_ui): Figure out how we want to add these
 173                // SettingsPageItem::SettingItem(SettingItem {
 174                //     title: "Theme Mode",
 175                //     description: "How to select the theme",
 176                //     field: Box::new(SettingField {
 177                //         pick: |settings_content| &settings_content.theme.theme,
 178                //         pick_mut: |settings_content| &mut settings_content.theme.theme,
 179                //     }),
 180                //     metadata: None,
 181                // }),
 182                // SettingsPageItem::SettingItem(SettingItem {
 183                //     title: "Icon Theme",
 184                //     // todo(settings_ui)
 185                //     // This description is misleading because the icon theme is used in more places than the file explorer)
 186                //     description: "Choose the icon theme for file explorer",
 187                //     field: Box::new(SettingField {
 188                //         pick: |settings_content| &settings_content.theme.icon_theme,
 189                //         pick_mut: |settings_content| &mut settings_content.theme.icon_theme,
 190                //     }),
 191                //     metadata: None,
 192                // }),
 193                SettingsPageItem::SectionHeader("Layout"),
 194                SettingsPageItem::SettingItem(SettingItem {
 195                    title: "Bottom Dock Layout",
 196                    description: "Layout mode for the bottom dock",
 197                    field: Box::new(SettingField {
 198                        pick: |settings_content| &settings_content.workspace.bottom_dock_layout,
 199                        pick_mut: |settings_content| {
 200                            &mut settings_content.workspace.bottom_dock_layout
 201                        },
 202                    }),
 203                    metadata: None,
 204                }),
 205                SettingsPageItem::SettingItem(SettingItem {
 206                    title: "Zoomed Padding",
 207                    description: "Whether to show padding for zoomed panels",
 208                    field: Box::new(SettingField {
 209                        pick: |settings_content| &settings_content.workspace.zoomed_padding,
 210                        pick_mut: |settings_content| &mut settings_content.workspace.zoomed_padding,
 211                    }),
 212                    metadata: None,
 213                }),
 214                SettingsPageItem::SettingItem(SettingItem {
 215                    title: "Use System Window Tabs",
 216                    description: "Whether to allow windows to tab together based on the user's tabbing preference (macOS only)",
 217                    field: Box::new(SettingField {
 218                        pick: |settings_content| &settings_content.workspace.use_system_window_tabs,
 219                        pick_mut: |settings_content| {
 220                            &mut settings_content.workspace.use_system_window_tabs
 221                        },
 222                    }),
 223                    metadata: None,
 224                }),
 225                SettingsPageItem::SectionHeader("Fonts"),
 226                SettingsPageItem::SettingItem(SettingItem {
 227                    title: "Buffer Font Family",
 228                    description: "Font family for editor text",
 229                    field: Box::new(SettingField {
 230                        pick: |settings_content| &settings_content.theme.buffer_font_family,
 231                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_family,
 232                    }),
 233                    metadata: None,
 234                }),
 235                SettingsPageItem::SettingItem(SettingItem {
 236                    title: "Buffer Font Size",
 237                    description: "Font size for editor text",
 238                    field: Box::new(SettingField {
 239                        pick: |settings_content| &settings_content.theme.buffer_font_size,
 240                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_size,
 241                    }),
 242                    metadata: None,
 243                }),
 244                SettingsPageItem::SettingItem(SettingItem {
 245                    title: "Buffer Font Weight",
 246                    description: "Font weight for editor text (100-900)",
 247                    field: Box::new(SettingField {
 248                        pick: |settings_content| &settings_content.theme.buffer_font_weight,
 249                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_weight,
 250                    }),
 251                    metadata: None,
 252                }),
 253                // todo(settings_ui): This needs custom ui
 254                // SettingsPageItem::SettingItem(SettingItem {
 255                //     title: "Buffer Line Height",
 256                //     description: "Line height for editor text",
 257                //     field: Box::new(SettingField {
 258                //         pick: |settings_content| &settings_content.theme.buffer_line_height,
 259                //         pick_mut: |settings_content| &mut settings_content.theme.buffer_line_height,
 260                //     }),
 261                //     metadata: None,
 262                // }),
 263                SettingsPageItem::SettingItem(SettingItem {
 264                    title: "UI Font Family",
 265                    description: "Font family for UI elements",
 266                    field: Box::new(SettingField {
 267                        pick: |settings_content| &settings_content.theme.ui_font_family,
 268                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_family,
 269                    }),
 270                    metadata: None,
 271                }),
 272                SettingsPageItem::SettingItem(SettingItem {
 273                    title: "UI Font Size",
 274                    description: "Font size for UI elements",
 275                    field: Box::new(SettingField {
 276                        pick: |settings_content| &settings_content.theme.ui_font_size,
 277                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_size,
 278                    }),
 279                    metadata: None,
 280                }),
 281                SettingsPageItem::SettingItem(SettingItem {
 282                    title: "UI Font Weight",
 283                    description: "Font weight for UI elements (100-900)",
 284                    field: Box::new(SettingField {
 285                        pick: |settings_content| &settings_content.theme.ui_font_weight,
 286                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_weight,
 287                    }),
 288                    metadata: None,
 289                }),
 290                SettingsPageItem::SectionHeader("Keymap"),
 291                SettingsPageItem::SettingItem(SettingItem {
 292                    title: "Base Keymap",
 293                    description: "The name of a base set of key bindings to use",
 294                    field: Box::new(SettingField {
 295                        pick: |settings_content| &settings_content.base_keymap,
 296                        pick_mut: |settings_content| &mut settings_content.base_keymap,
 297                    }),
 298                    metadata: None,
 299                }),
 300                // todo(settings_ui): Vim/Helix Mode should be apart of one type because it's undefined
 301                // behavior to have them both enabled at the same time
 302                SettingsPageItem::SettingItem(SettingItem {
 303                    title: "Vim Mode",
 304                    description: "Whether to enable vim modes and key bindings",
 305                    field: Box::new(SettingField {
 306                        pick: |settings_content| &settings_content.vim_mode,
 307                        pick_mut: |settings_content| &mut settings_content.vim_mode,
 308                    }),
 309                    metadata: None,
 310                }),
 311                SettingsPageItem::SettingItem(SettingItem {
 312                    title: "Helix Mode",
 313                    description: "Whether to enable helix modes and key bindings",
 314                    field: Box::new(SettingField {
 315                        pick: |settings_content| &settings_content.helix_mode,
 316                        pick_mut: |settings_content| &mut settings_content.helix_mode,
 317                    }),
 318                    metadata: None,
 319                }),
 320                SettingsPageItem::SettingItem(SettingItem {
 321                    title: "Multi Cursor Modifier",
 322                    description: "Modifier key for adding multiple cursors",
 323                    field: Box::new(SettingField {
 324                        pick: |settings_content| &settings_content.editor.multi_cursor_modifier,
 325                        pick_mut: |settings_content| {
 326                            &mut settings_content.editor.multi_cursor_modifier
 327                        },
 328                    }),
 329                    metadata: None,
 330                }),
 331                SettingsPageItem::SectionHeader("Cursor"),
 332                SettingsPageItem::SettingItem(SettingItem {
 333                    title: "Cursor Blink",
 334                    description: "Whether the cursor blinks in the editor",
 335                    field: Box::new(SettingField {
 336                        pick: |settings_content| &settings_content.editor.cursor_blink,
 337                        pick_mut: |settings_content| &mut settings_content.editor.cursor_blink,
 338                    }),
 339                    metadata: None,
 340                }),
 341                SettingsPageItem::SettingItem(SettingItem {
 342                    title: "Cursor Shape",
 343                    description: "Cursor shape for the editor",
 344                    field: Box::new(SettingField {
 345                        pick: |settings_content| &settings_content.editor.cursor_shape,
 346                        pick_mut: |settings_content| &mut settings_content.editor.cursor_shape,
 347                    }),
 348                    metadata: None,
 349                }),
 350                SettingsPageItem::SettingItem(SettingItem {
 351                    title: "Hide Mouse",
 352                    description: "When to hide the mouse cursor",
 353                    field: Box::new(SettingField {
 354                        pick: |settings_content| &settings_content.editor.hide_mouse,
 355                        pick_mut: |settings_content| &mut settings_content.editor.hide_mouse,
 356                    }),
 357                    metadata: None,
 358                }),
 359                SettingsPageItem::SectionHeader("Highlighting"),
 360                SettingsPageItem::SettingItem(SettingItem {
 361                    title: "Unnecessary Code Fade",
 362                    description: "How much to fade out unused code (0.0 - 0.9)",
 363                    field: Box::new(SettingField {
 364                        pick: |settings_content| &settings_content.theme.unnecessary_code_fade,
 365                        pick_mut: |settings_content| {
 366                            &mut settings_content.theme.unnecessary_code_fade
 367                        },
 368                    }),
 369                    metadata: None,
 370                }),
 371                SettingsPageItem::SettingItem(SettingItem {
 372                    title: "Current Line Highlight",
 373                    description: "How to highlight the current line",
 374                    field: Box::new(SettingField {
 375                        pick: |settings_content| &settings_content.editor.current_line_highlight,
 376                        pick_mut: |settings_content| {
 377                            &mut settings_content.editor.current_line_highlight
 378                        },
 379                    }),
 380                    metadata: None,
 381                }),
 382                SettingsPageItem::SettingItem(SettingItem {
 383                    title: "Selection Highlight",
 384                    description: "Whether to highlight all occurrences of selected text",
 385                    field: Box::new(SettingField {
 386                        pick: |settings_content| &settings_content.editor.selection_highlight,
 387                        pick_mut: |settings_content| {
 388                            &mut settings_content.editor.selection_highlight
 389                        },
 390                    }),
 391                    metadata: None,
 392                }),
 393                SettingsPageItem::SettingItem(SettingItem {
 394                    title: "Rounded Selection",
 395                    description: "Whether the text selection should have rounded corners",
 396                    field: Box::new(SettingField {
 397                        pick: |settings_content| &settings_content.editor.rounded_selection,
 398                        pick_mut: |settings_content| &mut settings_content.editor.rounded_selection,
 399                    }),
 400                    metadata: None,
 401                }),
 402                SettingsPageItem::SectionHeader("Guides"),
 403                SettingsPageItem::SettingItem(SettingItem {
 404                    title: "Show Wrap Guides",
 405                    description: "Whether to show wrap guides (vertical rulers)",
 406                    field: Box::new(SettingField {
 407                        pick: |settings_content| {
 408                            &settings_content
 409                                .project
 410                                .all_languages
 411                                .defaults
 412                                .show_wrap_guides
 413                        },
 414                        pick_mut: |settings_content| {
 415                            &mut settings_content
 416                                .project
 417                                .all_languages
 418                                .defaults
 419                                .show_wrap_guides
 420                        },
 421                    }),
 422                    metadata: None,
 423                }),
 424                // todo(settings_ui): This needs a custom component
 425                // SettingsPageItem::SettingItem(SettingItem {
 426                //     title: "Wrap Guides",
 427                //     description: "Character counts at which to show wrap guides",
 428                //     field: Box::new(SettingField {
 429                //         pick: |settings_content| {
 430                //             &settings_content
 431                //                 .project
 432                //                 .all_languages
 433                //                 .defaults
 434                //                 .wrap_guides
 435                //         },
 436                //         pick_mut: |settings_content| {
 437                //             &mut settings_content
 438                //                 .project
 439                //                 .all_languages
 440                //                 .defaults
 441                //                 .wrap_guides
 442                //         },
 443                //     }),
 444                //     metadata: None,
 445                // }),
 446                SettingsPageItem::SectionHeader("Whitespace"),
 447                SettingsPageItem::SettingItem(SettingItem {
 448                    title: "Show Whitespace",
 449                    description: "Whether to show tabs and spaces",
 450                    field: Box::new(SettingField {
 451                        pick: |settings_content| {
 452                            &settings_content
 453                                .project
 454                                .all_languages
 455                                .defaults
 456                                .show_whitespaces
 457                        },
 458                        pick_mut: |settings_content| {
 459                            &mut settings_content
 460                                .project
 461                                .all_languages
 462                                .defaults
 463                                .show_whitespaces
 464                        },
 465                    }),
 466                    metadata: None,
 467                }),
 468                SettingsPageItem::SectionHeader("Window"),
 469                // todo(settings_ui): Should we filter by platform?
 470                SettingsPageItem::SettingItem(SettingItem {
 471                    title: "Use System Window Tabs",
 472                    description: "Whether to allow windows to tab together (macOS only)",
 473                    field: Box::new(SettingField {
 474                        pick: |settings_content| &settings_content.workspace.use_system_window_tabs,
 475                        pick_mut: |settings_content| {
 476                            &mut settings_content.workspace.use_system_window_tabs
 477                        },
 478                    }),
 479                    metadata: None,
 480                }),
 481                SettingsPageItem::SectionHeader("Layout"),
 482                SettingsPageItem::SettingItem(SettingItem {
 483                    title: "Zoomed Padding",
 484                    description: "Whether to show padding for zoomed panels",
 485                    field: Box::new(SettingField {
 486                        pick: |settings_content| &settings_content.workspace.zoomed_padding,
 487                        pick_mut: |settings_content| &mut settings_content.workspace.zoomed_padding,
 488                    }),
 489                    metadata: None,
 490                }),
 491                // todo(settings_ui): Needs numeric stepper + option within an option
 492                // SettingsPageItem::SettingItem(SettingItem {
 493                //     title: "Centered Layout Left Padding",
 494                //     description: "Left padding for centered layout",
 495                //     field: Box::new(SettingField {
 496                //         pick: |settings_content| {
 497                //             &settings_content.workspace.centered_layout.left_padding
 498                //         },
 499                //         pick_mut: |settings_content| {
 500                //             &mut settings_content.workspace.centered_layout.left_padding
 501                //         },
 502                //     }),
 503                //     metadata: None,
 504                // }),
 505                // SettingsPageItem::SettingItem(SettingItem {
 506                //     title: "Centered Layout Right Padding",
 507                //     description: "Right padding for centered layout",
 508                //     field: Box::new(SettingField {
 509                //         pick: |settings_content| {
 510                //             if let Some(centered_layout) =
 511                //                 &settings_content.workspace.centered_layout
 512                //             {
 513                //                 &centered_layout.right_padding
 514                //             } else {
 515                //                 &None
 516                //             }
 517                //         },
 518                //         pick_mut: |settings_content| {
 519                //             if let Some(mut centered_layout) =
 520                //                 settings_content.workspace.centered_layout
 521                //             {
 522                //                 &mut centered_layout.right_padding
 523                //             } else {
 524                //                 &mut None
 525                //             }
 526                //         },
 527                //     }),
 528                //     metadata: None,
 529                // }),
 530                SettingsPageItem::SettingItem(SettingItem {
 531                    title: "Bottom Dock Layout",
 532                    description: "Layout mode of the bottom dock",
 533                    field: Box::new(SettingField {
 534                        pick: |settings_content| &settings_content.workspace.bottom_dock_layout,
 535                        pick_mut: |settings_content| {
 536                            &mut settings_content.workspace.bottom_dock_layout
 537                        },
 538                    }),
 539                    metadata: None,
 540                }),
 541            ],
 542        },
 543        SettingsPage {
 544            title: "Editor",
 545            items: vec![
 546                SettingsPageItem::SectionHeader("Indentation"),
 547                // todo(settings_ui): Needs numeric stepper
 548                SettingsPageItem::SettingItem(SettingItem {
 549                    title: "Tab Size",
 550                    description: "How many columns a tab should occupy",
 551                    field: Box::new(SettingField {
 552                        pick: |settings_content| {
 553                            &settings_content.project.all_languages.defaults.tab_size
 554                        },
 555                        pick_mut: |settings_content| {
 556                            &mut settings_content.project.all_languages.defaults.tab_size
 557                        },
 558                    }),
 559                    metadata: None,
 560                }),
 561                SettingsPageItem::SettingItem(SettingItem {
 562                    title: "Hard Tabs",
 563                    description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
 564                    field: Box::new(SettingField {
 565                        pick: |settings_content| {
 566                            &settings_content.project.all_languages.defaults.hard_tabs
 567                        },
 568                        pick_mut: |settings_content| {
 569                            &mut settings_content.project.all_languages.defaults.hard_tabs
 570                        },
 571                    }),
 572                    metadata: None,
 573                }),
 574                SettingsPageItem::SettingItem(SettingItem {
 575                    title: "Auto Indent",
 576                    description: "Whether indentation should be adjusted based on the context whilst typing",
 577                    field: Box::new(SettingField {
 578                        pick: |settings_content| {
 579                            &settings_content.project.all_languages.defaults.auto_indent
 580                        },
 581                        pick_mut: |settings_content| {
 582                            &mut settings_content.project.all_languages.defaults.auto_indent
 583                        },
 584                    }),
 585                    metadata: None,
 586                }),
 587                SettingsPageItem::SettingItem(SettingItem {
 588                    title: "Auto Indent On Paste",
 589                    description: "Whether indentation of pasted content should be adjusted based on the context",
 590                    field: Box::new(SettingField {
 591                        pick: |settings_content| {
 592                            &settings_content
 593                                .project
 594                                .all_languages
 595                                .defaults
 596                                .auto_indent_on_paste
 597                        },
 598                        pick_mut: |settings_content| {
 599                            &mut settings_content
 600                                .project
 601                                .all_languages
 602                                .defaults
 603                                .auto_indent_on_paste
 604                        },
 605                    }),
 606                    metadata: None,
 607                }),
 608                SettingsPageItem::SectionHeader("Wrapping"),
 609                // todo(settings_ui): Needs numeric stepper
 610                // SettingsPageItem::SettingItem(SettingItem {
 611                //     title: "Preferred Line Length",
 612                //     description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
 613                //     field: Box::new(SettingField {
 614                //         pick: |settings_content| &settings_content.project.all_languages.defaults.preferred_line_length,
 615                //         pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.preferred_line_length,
 616                //     }),
 617                //     metadata: None,
 618                // }),
 619                SettingsPageItem::SettingItem(SettingItem {
 620                    title: "Soft Wrap",
 621                    description: "How to soft-wrap long lines of text",
 622                    field: Box::new(SettingField {
 623                        pick: |settings_content| {
 624                            &settings_content.project.all_languages.defaults.soft_wrap
 625                        },
 626                        pick_mut: |settings_content| {
 627                            &mut settings_content.project.all_languages.defaults.soft_wrap
 628                        },
 629                    }),
 630                    metadata: None,
 631                }),
 632                SettingsPageItem::SectionHeader("Search"),
 633                SettingsPageItem::SettingItem(SettingItem {
 634                    title: "Search Wrap",
 635                    description: "Whether the editor search results will loop",
 636                    field: Box::new(SettingField {
 637                        pick: |settings_content| &settings_content.editor.search_wrap,
 638                        pick_mut: |settings_content| &mut settings_content.editor.search_wrap,
 639                    }),
 640                    metadata: None,
 641                }),
 642                SettingsPageItem::SettingItem(SettingItem {
 643                    title: "Seed Search Query From Cursor",
 644                    description: "When to populate a new search's query based on the text under the cursor",
 645                    field: Box::new(SettingField {
 646                        pick: |settings_content| {
 647                            &settings_content.editor.seed_search_query_from_cursor
 648                        },
 649                        pick_mut: |settings_content| {
 650                            &mut settings_content.editor.seed_search_query_from_cursor
 651                        },
 652                    }),
 653                    metadata: None,
 654                }),
 655                SettingsPageItem::SettingItem(SettingItem {
 656                    title: "Use Smartcase Search",
 657                    description: "Whether to use smartcase search",
 658                    field: Box::new(SettingField {
 659                        pick: |settings_content| &settings_content.editor.use_smartcase_search,
 660                        pick_mut: |settings_content| {
 661                            &mut settings_content.editor.use_smartcase_search
 662                        },
 663                    }),
 664                    metadata: None,
 665                }),
 666                SettingsPageItem::SectionHeader("Editor Behavior"),
 667                SettingsPageItem::SettingItem(SettingItem {
 668                    title: "Redact Private Values",
 669                    description: "Hide the values of variables in private files",
 670                    field: Box::new(SettingField {
 671                        pick: |settings_content| &settings_content.editor.redact_private_values,
 672                        pick_mut: |settings_content| {
 673                            &mut settings_content.editor.redact_private_values
 674                        },
 675                    }),
 676                    metadata: None,
 677                }),
 678                SettingsPageItem::SettingItem(SettingItem {
 679                    title: "Middle Click Paste",
 680                    description: "Whether to enable middle-click paste on Linux",
 681                    field: Box::new(SettingField {
 682                        pick: |settings_content| &settings_content.editor.middle_click_paste,
 683                        pick_mut: |settings_content| {
 684                            &mut settings_content.editor.middle_click_paste
 685                        },
 686                    }),
 687                    metadata: None,
 688                }),
 689                SettingsPageItem::SettingItem(SettingItem {
 690                    title: "Double Click In Multibuffer",
 691                    description: "What to do when multibuffer is double clicked in some of its excerpts",
 692                    field: Box::new(SettingField {
 693                        pick: |settings_content| {
 694                            &settings_content.editor.double_click_in_multibuffer
 695                        },
 696                        pick_mut: |settings_content| {
 697                            &mut settings_content.editor.double_click_in_multibuffer
 698                        },
 699                    }),
 700                    metadata: None,
 701                }),
 702                SettingsPageItem::SettingItem(SettingItem {
 703                    title: "Go To Definition Fallback",
 704                    description: "Whether to follow-up empty go to definition responses from the language server",
 705                    field: Box::new(SettingField {
 706                        pick: |settings_content| &settings_content.editor.go_to_definition_fallback,
 707                        pick_mut: |settings_content| {
 708                            &mut settings_content.editor.go_to_definition_fallback
 709                        },
 710                    }),
 711                    metadata: None,
 712                }),
 713                SettingsPageItem::SectionHeader("Scrolling"),
 714                SettingsPageItem::SettingItem(SettingItem {
 715                    title: "Scroll Beyond Last Line",
 716                    description: "Whether the editor will scroll beyond the last line",
 717                    field: Box::new(SettingField {
 718                        pick: |settings_content| &settings_content.editor.scroll_beyond_last_line,
 719                        pick_mut: |settings_content| {
 720                            &mut settings_content.editor.scroll_beyond_last_line
 721                        },
 722                    }),
 723                    metadata: None,
 724                }),
 725                SettingsPageItem::SettingItem(SettingItem {
 726                    title: "Vertical Scroll Margin",
 727                    description: "The number of lines to keep above/below the cursor when auto-scrolling",
 728                    field: Box::new(SettingField {
 729                        pick: |settings_content| &settings_content.editor.vertical_scroll_margin,
 730                        pick_mut: |settings_content| {
 731                            &mut settings_content.editor.vertical_scroll_margin
 732                        },
 733                    }),
 734                    metadata: None,
 735                }),
 736                SettingsPageItem::SettingItem(SettingItem {
 737                    title: "Horizontal Scroll Margin",
 738                    description: "The number of characters to keep on either side when scrolling with the mouse",
 739                    field: Box::new(SettingField {
 740                        pick: |settings_content| &settings_content.editor.horizontal_scroll_margin,
 741                        pick_mut: |settings_content| {
 742                            &mut settings_content.editor.horizontal_scroll_margin
 743                        },
 744                    }),
 745                    metadata: None,
 746                }),
 747                SettingsPageItem::SettingItem(SettingItem {
 748                    title: "Scroll Sensitivity",
 749                    description: "Scroll sensitivity multiplier for both horizontal and vertical scrolling",
 750                    field: Box::new(SettingField {
 751                        pick: |settings_content| &settings_content.editor.scroll_sensitivity,
 752                        pick_mut: |settings_content| {
 753                            &mut settings_content.editor.scroll_sensitivity
 754                        },
 755                    }),
 756                    metadata: None,
 757                }),
 758                SettingsPageItem::SettingItem(SettingItem {
 759                    title: "Fast Scroll Sensitivity",
 760                    description: "Fast Scroll sensitivity multiplier for both horizontal and vertical scrolling",
 761                    field: Box::new(SettingField {
 762                        pick: |settings_content| &settings_content.editor.fast_scroll_sensitivity,
 763                        pick_mut: |settings_content| {
 764                            &mut settings_content.editor.fast_scroll_sensitivity
 765                        },
 766                    }),
 767                    metadata: None,
 768                }),
 769                SettingsPageItem::SettingItem(SettingItem {
 770                    title: "Autoscroll On Clicks",
 771                    description: "Whether to scroll when clicking near the edge of the visible text area",
 772                    field: Box::new(SettingField {
 773                        pick: |settings_content| &settings_content.editor.autoscroll_on_clicks,
 774                        pick_mut: |settings_content| {
 775                            &mut settings_content.editor.autoscroll_on_clicks
 776                        },
 777                    }),
 778                    metadata: None,
 779                }),
 780                SettingsPageItem::SectionHeader("Auto Actions"),
 781                SettingsPageItem::SettingItem(SettingItem {
 782                    title: "Use Autoclose",
 783                    description: "Whether to automatically type closing characters for you",
 784                    field: Box::new(SettingField {
 785                        pick: |settings_content| {
 786                            &settings_content
 787                                .project
 788                                .all_languages
 789                                .defaults
 790                                .use_autoclose
 791                        },
 792                        pick_mut: |settings_content| {
 793                            &mut settings_content
 794                                .project
 795                                .all_languages
 796                                .defaults
 797                                .use_autoclose
 798                        },
 799                    }),
 800                    metadata: None,
 801                }),
 802                SettingsPageItem::SettingItem(SettingItem {
 803                    title: "Use Auto Surround",
 804                    description: "Whether to automatically surround text with characters for you",
 805                    field: Box::new(SettingField {
 806                        pick: |settings_content| {
 807                            &settings_content
 808                                .project
 809                                .all_languages
 810                                .defaults
 811                                .use_auto_surround
 812                        },
 813                        pick_mut: |settings_content| {
 814                            &mut settings_content
 815                                .project
 816                                .all_languages
 817                                .defaults
 818                                .use_auto_surround
 819                        },
 820                    }),
 821                    metadata: None,
 822                }),
 823                SettingsPageItem::SettingItem(SettingItem {
 824                    title: "Use On Type Format",
 825                    description: "Whether to use additional LSP queries to format the code after every trigger symbol input",
 826                    field: Box::new(SettingField {
 827                        pick: |settings_content| {
 828                            &settings_content
 829                                .project
 830                                .all_languages
 831                                .defaults
 832                                .use_on_type_format
 833                        },
 834                        pick_mut: |settings_content| {
 835                            &mut settings_content
 836                                .project
 837                                .all_languages
 838                                .defaults
 839                                .use_on_type_format
 840                        },
 841                    }),
 842                    metadata: None,
 843                }),
 844                SettingsPageItem::SettingItem(SettingItem {
 845                    title: "Always Treat Brackets As Autoclosed",
 846                    description: "Controls how the editor handles the autoclosed characters",
 847                    field: Box::new(SettingField {
 848                        pick: |settings_content| {
 849                            &settings_content
 850                                .project
 851                                .all_languages
 852                                .defaults
 853                                .always_treat_brackets_as_autoclosed
 854                        },
 855                        pick_mut: |settings_content| {
 856                            &mut settings_content
 857                                .project
 858                                .all_languages
 859                                .defaults
 860                                .always_treat_brackets_as_autoclosed
 861                        },
 862                    }),
 863                    metadata: None,
 864                }),
 865                SettingsPageItem::SectionHeader("Formatting"),
 866                SettingsPageItem::SettingItem(SettingItem {
 867                    title: "Remove Trailing Whitespace On Save",
 868                    description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
 869                    field: Box::new(SettingField {
 870                        pick: |settings_content| {
 871                            &settings_content
 872                                .project
 873                                .all_languages
 874                                .defaults
 875                                .remove_trailing_whitespace_on_save
 876                        },
 877                        pick_mut: |settings_content| {
 878                            &mut settings_content
 879                                .project
 880                                .all_languages
 881                                .defaults
 882                                .remove_trailing_whitespace_on_save
 883                        },
 884                    }),
 885                    metadata: None,
 886                }),
 887                SettingsPageItem::SettingItem(SettingItem {
 888                    title: "Ensure Final Newline On Save",
 889                    description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
 890                    field: Box::new(SettingField {
 891                        pick: |settings_content| {
 892                            &settings_content
 893                                .project
 894                                .all_languages
 895                                .defaults
 896                                .ensure_final_newline_on_save
 897                        },
 898                        pick_mut: |settings_content| {
 899                            &mut settings_content
 900                                .project
 901                                .all_languages
 902                                .defaults
 903                                .ensure_final_newline_on_save
 904                        },
 905                    }),
 906                    metadata: None,
 907                }),
 908                SettingsPageItem::SettingItem(SettingItem {
 909                    title: "Extend Comment On Newline",
 910                    description: "Whether to start a new line with a comment when a previous line is a comment as well",
 911                    field: Box::new(SettingField {
 912                        pick: |settings_content| {
 913                            &settings_content
 914                                .project
 915                                .all_languages
 916                                .defaults
 917                                .extend_comment_on_newline
 918                        },
 919                        pick_mut: |settings_content| {
 920                            &mut settings_content
 921                                .project
 922                                .all_languages
 923                                .defaults
 924                                .extend_comment_on_newline
 925                        },
 926                    }),
 927                    metadata: None,
 928                }),
 929                SettingsPageItem::SectionHeader("Completions"),
 930                SettingsPageItem::SettingItem(SettingItem {
 931                    title: "Show Completions On Input",
 932                    description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
 933                    field: Box::new(SettingField {
 934                        pick: |settings_content| {
 935                            &settings_content
 936                                .project
 937                                .all_languages
 938                                .defaults
 939                                .show_completions_on_input
 940                        },
 941                        pick_mut: |settings_content| {
 942                            &mut settings_content
 943                                .project
 944                                .all_languages
 945                                .defaults
 946                                .show_completions_on_input
 947                        },
 948                    }),
 949                    metadata: None,
 950                }),
 951                SettingsPageItem::SettingItem(SettingItem {
 952                    title: "Show Completion Documentation",
 953                    description: "Whether to display inline and alongside documentation for items in the completions menu",
 954                    field: Box::new(SettingField {
 955                        pick: |settings_content| {
 956                            &settings_content
 957                                .project
 958                                .all_languages
 959                                .defaults
 960                                .show_completion_documentation
 961                        },
 962                        pick_mut: |settings_content| {
 963                            &mut settings_content
 964                                .project
 965                                .all_languages
 966                                .defaults
 967                                .show_completion_documentation
 968                        },
 969                    }),
 970                    metadata: None,
 971                }),
 972                SettingsPageItem::SettingItem(SettingItem {
 973                    title: "Auto Signature Help",
 974                    description: "Whether to automatically show a signature help pop-up or not",
 975                    field: Box::new(SettingField {
 976                        pick: |settings_content| &settings_content.editor.auto_signature_help,
 977                        pick_mut: |settings_content| {
 978                            &mut settings_content.editor.auto_signature_help
 979                        },
 980                    }),
 981                    metadata: None,
 982                }),
 983                SettingsPageItem::SettingItem(SettingItem {
 984                    title: "Show Signature Help After Edits",
 985                    description: "Whether to show the signature help pop-up after completions or bracket pairs inserted",
 986                    field: Box::new(SettingField {
 987                        pick: |settings_content| {
 988                            &settings_content.editor.show_signature_help_after_edits
 989                        },
 990                        pick_mut: |settings_content| {
 991                            &mut settings_content.editor.show_signature_help_after_edits
 992                        },
 993                    }),
 994                    metadata: None,
 995                }),
 996                SettingsPageItem::SettingItem(SettingItem {
 997                    title: "Snippet Sort Order",
 998                    description: "Determines how snippets are sorted relative to other completion items",
 999                    field: Box::new(SettingField {
1000                        pick: |settings_content| &settings_content.editor.snippet_sort_order,
1001                        pick_mut: |settings_content| {
1002                            &mut settings_content.editor.snippet_sort_order
1003                        },
1004                    }),
1005                    metadata: None,
1006                }),
1007                SettingsPageItem::SectionHeader("Hover"),
1008                SettingsPageItem::SettingItem(SettingItem {
1009                    title: "Hover Popover Enabled",
1010                    description: "Whether to show the informational hover box when moving the mouse over symbols in the editor",
1011                    field: Box::new(SettingField {
1012                        pick: |settings_content| &settings_content.editor.hover_popover_enabled,
1013                        pick_mut: |settings_content| {
1014                            &mut settings_content.editor.hover_popover_enabled
1015                        },
1016                    }),
1017                    metadata: None,
1018                }),
1019                // todo(settings ui): add units to this numeric stepper
1020                SettingsPageItem::SettingItem(SettingItem {
1021                    title: "Hover Popover Delay",
1022                    description: "Time to wait in milliseconds before showing the informational hover box",
1023                    field: Box::new(SettingField {
1024                        pick: |settings_content| &settings_content.editor.hover_popover_delay,
1025                        pick_mut: |settings_content| {
1026                            &mut settings_content.editor.hover_popover_delay
1027                        },
1028                    }),
1029                    metadata: None,
1030                }),
1031                SettingsPageItem::SectionHeader("Code Actions"),
1032                SettingsPageItem::SettingItem(SettingItem {
1033                    title: "Inline Code Actions",
1034                    description: "Whether to show code action button at start of buffer line",
1035                    field: Box::new(SettingField {
1036                        pick: |settings_content| &settings_content.editor.inline_code_actions,
1037                        pick_mut: |settings_content| {
1038                            &mut settings_content.editor.inline_code_actions
1039                        },
1040                    }),
1041                    metadata: None,
1042                }),
1043                SettingsPageItem::SectionHeader("Selection"),
1044                SettingsPageItem::SettingItem(SettingItem {
1045                    title: "Drag And Drop Selection",
1046                    description: "Whether to enable drag and drop selection",
1047                    field: Box::new(SettingField {
1048                        pick: |settings_content| {
1049                            if let Some(drag_and_drop) =
1050                                &settings_content.editor.drag_and_drop_selection
1051                            {
1052                                &drag_and_drop.enabled
1053                            } else {
1054                                &None
1055                            }
1056                        },
1057                        pick_mut: |settings_content| {
1058                            &mut settings_content
1059                                .editor
1060                                .drag_and_drop_selection
1061                                .get_or_insert_default()
1062                                .enabled
1063                        },
1064                    }),
1065                    metadata: None,
1066                }),
1067                // todo(settings_ui): Needs numeric stepper
1068                // SettingsPageItem::SettingItem(SettingItem {
1069                //     title: "Drag And Drop Selection Delay",
1070                //     description: "Delay in milliseconds before drag and drop selection starts",
1071                //     field: Box::new(SettingField {
1072                //         pick: |settings_content| {
1073                //             if let Some(drag_and_drop) = &settings_content.editor.drag_and_drop_selection {
1074                //                 &drag_and_drop.delay
1075                //             } else {
1076                //                 &None
1077                //             }
1078                //         },
1079                //         pick_mut: |settings_content| {
1080                //             &mut settings_content.editor.drag_and_drop_selection.get_or_insert_default().delay
1081                //         },
1082                //     }),
1083                //     metadata: None,
1084                // }),
1085                SettingsPageItem::SectionHeader("Line Numbers"),
1086                SettingsPageItem::SettingItem(SettingItem {
1087                    title: "Relative Line Numbers",
1088                    description: "Whether the line numbers on editors gutter are relative or not",
1089                    field: Box::new(SettingField {
1090                        pick: |settings_content| &settings_content.editor.relative_line_numbers,
1091                        pick_mut: |settings_content| {
1092                            &mut settings_content.editor.relative_line_numbers
1093                        },
1094                    }),
1095                    metadata: None,
1096                }),
1097                SettingsPageItem::SectionHeader("Gutter"),
1098                SettingsPageItem::SettingItem(SettingItem {
1099                    title: "Show Line Numbers",
1100                    description: "Whether to show line numbers in the gutter",
1101                    field: Box::new(SettingField {
1102                        pick: |settings_content| {
1103                            if let Some(gutter) = &settings_content.editor.gutter {
1104                                &gutter.line_numbers
1105                            } else {
1106                                &None
1107                            }
1108                        },
1109                        pick_mut: |settings_content| {
1110                            &mut settings_content
1111                                .editor
1112                                .gutter
1113                                .get_or_insert_default()
1114                                .line_numbers
1115                        },
1116                    }),
1117                    metadata: None,
1118                }),
1119                SettingsPageItem::SettingItem(SettingItem {
1120                    title: "Show Runnables",
1121                    description: "Whether to show runnable buttons in the gutter",
1122                    field: Box::new(SettingField {
1123                        pick: |settings_content| {
1124                            if let Some(gutter) = &settings_content.editor.gutter {
1125                                &gutter.runnables
1126                            } else {
1127                                &None
1128                            }
1129                        },
1130                        pick_mut: |settings_content| {
1131                            &mut settings_content
1132                                .editor
1133                                .gutter
1134                                .get_or_insert_default()
1135                                .runnables
1136                        },
1137                    }),
1138                    metadata: None,
1139                }),
1140                SettingsPageItem::SettingItem(SettingItem {
1141                    title: "Show Breakpoints",
1142                    description: "Whether to show breakpoints in the gutter",
1143                    field: Box::new(SettingField {
1144                        pick: |settings_content| {
1145                            if let Some(gutter) = &settings_content.editor.gutter {
1146                                &gutter.breakpoints
1147                            } else {
1148                                &None
1149                            }
1150                        },
1151                        pick_mut: |settings_content| {
1152                            &mut settings_content
1153                                .editor
1154                                .gutter
1155                                .get_or_insert_default()
1156                                .breakpoints
1157                        },
1158                    }),
1159                    metadata: None,
1160                }),
1161                SettingsPageItem::SettingItem(SettingItem {
1162                    title: "Show Folds",
1163                    description: "Whether to show code folding controls in the gutter",
1164                    field: Box::new(SettingField {
1165                        pick: |settings_content| {
1166                            if let Some(gutter) = &settings_content.editor.gutter {
1167                                &gutter.folds
1168                            } else {
1169                                &None
1170                            }
1171                        },
1172                        pick_mut: |settings_content| {
1173                            &mut settings_content.editor.gutter.get_or_insert_default().folds
1174                        },
1175                    }),
1176                    metadata: None,
1177                }),
1178                SettingsPageItem::SectionHeader("Tabs"),
1179                SettingsPageItem::SettingItem(SettingItem {
1180                    title: "Show Tab Bar",
1181                    description: "Whether or not to show the tab bar in the editor",
1182                    field: Box::new(SettingField {
1183                        pick: |settings_content| {
1184                            if let Some(tab_bar) = &settings_content.tab_bar {
1185                                &tab_bar.show
1186                            } else {
1187                                &None
1188                            }
1189                        },
1190                        pick_mut: |settings_content| {
1191                            &mut settings_content.tab_bar.get_or_insert_default().show
1192                        },
1193                    }),
1194                    metadata: None,
1195                }),
1196                SettingsPageItem::SettingItem(SettingItem {
1197                    title: "Show Git Status In Tabs",
1198                    description: "Whether to show the Git file status on a tab item",
1199                    field: Box::new(SettingField {
1200                        pick: |settings_content| {
1201                            if let Some(tabs) = &settings_content.tabs {
1202                                &tabs.git_status
1203                            } else {
1204                                &None
1205                            }
1206                        },
1207                        pick_mut: |settings_content| {
1208                            &mut settings_content.tabs.get_or_insert_default().git_status
1209                        },
1210                    }),
1211                    metadata: None,
1212                }),
1213                SettingsPageItem::SettingItem(SettingItem {
1214                    title: "Show File Icons In Tabs",
1215                    description: "Whether to show the file icon for a tab",
1216                    field: Box::new(SettingField {
1217                        pick: |settings_content| {
1218                            if let Some(tabs) = &settings_content.tabs {
1219                                &tabs.file_icons
1220                            } else {
1221                                &None
1222                            }
1223                        },
1224                        pick_mut: |settings_content| {
1225                            &mut settings_content.tabs.get_or_insert_default().file_icons
1226                        },
1227                    }),
1228                    metadata: None,
1229                }),
1230                SettingsPageItem::SettingItem(SettingItem {
1231                    title: "Tab Close Position",
1232                    description: "Position of the close button in a tab",
1233                    field: Box::new(SettingField {
1234                        pick: |settings_content| {
1235                            if let Some(tabs) = &settings_content.tabs {
1236                                &tabs.close_position
1237                            } else {
1238                                &None
1239                            }
1240                        },
1241                        pick_mut: |settings_content| {
1242                            &mut settings_content.tabs.get_or_insert_default().close_position
1243                        },
1244                    }),
1245                    metadata: None,
1246                }),
1247                // todo(settings_ui): Needs numeric stepper
1248                // SettingsPageItem::SettingItem(SettingItem {
1249                //     title: "Maximum Tabs",
1250                //     description: "Maximum open tabs in a pane. Will not close an unsaved tab",
1251                //     field: Box::new(SettingField {
1252                //         pick: |settings_content| &settings_content.workspace.max_tabs,
1253                //         pick_mut: |settings_content| &mut settings_content.workspace.max_tabs,
1254                //     }),
1255                //     metadata: None,
1256                // }),
1257            ],
1258        },
1259        SettingsPage {
1260            title: "Languages & Frameworks",
1261            items: vec![
1262                SettingsPageItem::SectionHeader("General"),
1263                SettingsPageItem::SettingItem(SettingItem {
1264                    title: "Enable Language Server",
1265                    description: "Whether to use language servers to provide code intelligence",
1266                    field: Box::new(SettingField {
1267                        pick: |settings_content| {
1268                            &settings_content
1269                                .project
1270                                .all_languages
1271                                .defaults
1272                                .enable_language_server
1273                        },
1274                        pick_mut: |settings_content| {
1275                            &mut settings_content
1276                                .project
1277                                .all_languages
1278                                .defaults
1279                                .enable_language_server
1280                        },
1281                    }),
1282                    metadata: None,
1283                }),
1284                SettingsPageItem::SectionHeader("Languages"),
1285                SettingsPageItem::SubPageLink(SubPageLink {
1286                    title: "JSON",
1287                    render: Rc::new(|_, _, _| "A settings page!".into_any_element()),
1288                }),
1289            ],
1290        },
1291        SettingsPage {
1292            title: "Workbench & Window",
1293            items: vec![
1294                SettingsPageItem::SectionHeader("Workbench"),
1295                SettingsPageItem::SettingItem(SettingItem {
1296                    title: "Editor Tabs",
1297                    description: "Whether or not to show the tab bar in the editor",
1298                    field: Box::new(SettingField {
1299                        pick: |settings_content| {
1300                            if let Some(tab_bar) = &settings_content.tab_bar {
1301                                &tab_bar.show
1302                            } else {
1303                                &None
1304                            }
1305                        },
1306                        pick_mut: |settings_content| {
1307                            &mut settings_content.tab_bar.get_or_insert_default().show
1308                        },
1309                    }),
1310                    metadata: None,
1311                }),
1312                SettingsPageItem::SettingItem(SettingItem {
1313                    title: "Active language Button",
1314                    description: "Whether to show the active language button in the status bar",
1315                    field: Box::new(SettingField {
1316                        pick: |settings_content| {
1317                            if let Some(status_bar) = &settings_content.status_bar {
1318                                &status_bar.active_language_button
1319                            } else {
1320                                &None
1321                            }
1322                        },
1323                        pick_mut: |settings_content| {
1324                            &mut settings_content
1325                                .status_bar
1326                                .get_or_insert_default()
1327                                .active_language_button
1328                        },
1329                    }),
1330                    metadata: None,
1331                }),
1332                SettingsPageItem::SettingItem(SettingItem {
1333                    title: "Cursor Position Button",
1334                    description: "Whether to show the cursor position button in the status bar",
1335                    field: Box::new(SettingField {
1336                        pick: |settings_content| {
1337                            if let Some(status_bar) = &settings_content.status_bar {
1338                                &status_bar.cursor_position_button
1339                            } else {
1340                                &None
1341                            }
1342                        },
1343                        pick_mut: |settings_content| {
1344                            &mut settings_content
1345                                .status_bar
1346                                .get_or_insert_default()
1347                                .cursor_position_button
1348                        },
1349                    }),
1350                    metadata: None,
1351                }),
1352                SettingsPageItem::SectionHeader("Terminal"),
1353                SettingsPageItem::SettingItem(SettingItem {
1354                    title: "Terminal Button",
1355                    description: "Whether to show the terminal button in the status bar",
1356                    field: Box::new(SettingField {
1357                        pick: |settings_content| {
1358                            if let Some(terminal) = &settings_content.terminal {
1359                                &terminal.button
1360                            } else {
1361                                &None
1362                            }
1363                        },
1364                        pick_mut: |settings_content| {
1365                            &mut settings_content.terminal.get_or_insert_default().button
1366                        },
1367                    }),
1368                    metadata: None,
1369                }),
1370                SettingsPageItem::SettingItem(SettingItem {
1371                    title: "Show Navigation History Buttons",
1372                    description: "Whether or not to show the navigation history buttons in the tab bar",
1373                    field: Box::new(SettingField {
1374                        pick: |settings_content| {
1375                            if let Some(tab_bar) = &settings_content.tab_bar {
1376                                &tab_bar.show_nav_history_buttons
1377                            } else {
1378                                &None
1379                            }
1380                        },
1381                        pick_mut: |settings_content| {
1382                            &mut settings_content
1383                                .tab_bar
1384                                .get_or_insert_default()
1385                                .show_nav_history_buttons
1386                        },
1387                    }),
1388                    metadata: None,
1389                }),
1390            ],
1391        },
1392        SettingsPage {
1393            title: "Panels & Tools",
1394            items: vec![
1395                SettingsPageItem::SectionHeader("Project Panel"),
1396                SettingsPageItem::SettingItem(SettingItem {
1397                    title: "Project Panel Button",
1398                    description: "Whether to show the project panel button in the status bar",
1399                    field: Box::new(SettingField {
1400                        pick: |settings_content| {
1401                            if let Some(project_panel) = &settings_content.project_panel {
1402                                &project_panel.button
1403                            } else {
1404                                &None
1405                            }
1406                        },
1407                        pick_mut: |settings_content| {
1408                            &mut settings_content
1409                                .project_panel
1410                                .get_or_insert_default()
1411                                .button
1412                        },
1413                    }),
1414                    metadata: None,
1415                }),
1416                SettingsPageItem::SettingItem(SettingItem {
1417                    title: "Project Panel Dock",
1418                    description: "Where to dock the project panel",
1419                    field: Box::new(SettingField {
1420                        pick: |settings_content| {
1421                            if let Some(project_panel) = &settings_content.project_panel {
1422                                &project_panel.dock
1423                            } else {
1424                                &None
1425                            }
1426                        },
1427                        pick_mut: |settings_content| {
1428                            &mut settings_content.project_panel.get_or_insert_default().dock
1429                        },
1430                    }),
1431                    metadata: None,
1432                }),
1433                // todo(settings_ui): Needs numeric stepper
1434                // SettingsPageItem::SettingItem(SettingItem {
1435                //     title: "Project Panel Default Width",
1436                //     description: "Default width of the project panel in pixels",
1437                //     field: Box::new(SettingField {
1438                //         pick: |settings_content| {
1439                //             if let Some(project_panel) = &settings_content.project_panel {
1440                //                 &project_panel.default_width
1441                //             } else {
1442                //                 &None
1443                //             }
1444                //         },
1445                //         pick_mut: |settings_content| {
1446                //             &mut settings_content
1447                //                 .project_panel
1448                //                 .get_or_insert_default()
1449                //                 .default_width
1450                //         },
1451                //     }),
1452                //     metadata: None,
1453                // }),
1454                SettingsPageItem::SectionHeader("Terminal"),
1455                SettingsPageItem::SettingItem(SettingItem {
1456                    title: "Terminal Dock",
1457                    description: "Where to dock the terminal panel",
1458                    field: Box::new(SettingField {
1459                        pick: |settings_content| {
1460                            if let Some(terminal) = &settings_content.terminal {
1461                                &terminal.dock
1462                            } else {
1463                                &None
1464                            }
1465                        },
1466                        pick_mut: |settings_content| {
1467                            &mut settings_content.terminal.get_or_insert_default().dock
1468                        },
1469                    }),
1470                    metadata: None,
1471                }),
1472                SettingsPageItem::SectionHeader("Tab Settings"),
1473                SettingsPageItem::SettingItem(SettingItem {
1474                    title: "Activate On Close",
1475                    description: "What to do after closing the current tab",
1476                    field: Box::new(SettingField {
1477                        pick: |settings_content| {
1478                            if let Some(tabs) = &settings_content.tabs {
1479                                &tabs.activate_on_close
1480                            } else {
1481                                &None
1482                            }
1483                        },
1484                        pick_mut: |settings_content| {
1485                            &mut settings_content
1486                                .tabs
1487                                .get_or_insert_default()
1488                                .activate_on_close
1489                        },
1490                    }),
1491                    metadata: None,
1492                }),
1493                SettingsPageItem::SettingItem(SettingItem {
1494                    title: "Tab Show Diagnostics",
1495                    description: "Which files containing diagnostic errors/warnings to mark in the tabs",
1496                    field: Box::new(SettingField {
1497                        pick: |settings_content| {
1498                            if let Some(tabs) = &settings_content.tabs {
1499                                &tabs.show_diagnostics
1500                            } else {
1501                                &None
1502                            }
1503                        },
1504                        pick_mut: |settings_content| {
1505                            &mut settings_content
1506                                .tabs
1507                                .get_or_insert_default()
1508                                .show_diagnostics
1509                        },
1510                    }),
1511                    metadata: None,
1512                }),
1513                SettingsPageItem::SettingItem(SettingItem {
1514                    title: "Show Close Button",
1515                    description: "Controls the appearance behavior of the tab's close button",
1516                    field: Box::new(SettingField {
1517                        pick: |settings_content| {
1518                            if let Some(tabs) = &settings_content.tabs {
1519                                &tabs.show_close_button
1520                            } else {
1521                                &None
1522                            }
1523                        },
1524                        pick_mut: |settings_content| {
1525                            &mut settings_content
1526                                .tabs
1527                                .get_or_insert_default()
1528                                .show_close_button
1529                        },
1530                    }),
1531                    metadata: None,
1532                }),
1533                SettingsPageItem::SectionHeader("Preview Tabs"),
1534                SettingsPageItem::SettingItem(SettingItem {
1535                    title: "Preview Tabs Enabled",
1536                    description: "Whether to show opened editors as preview tabs",
1537                    field: Box::new(SettingField {
1538                        pick: |settings_content| {
1539                            if let Some(preview_tabs) = &settings_content.preview_tabs {
1540                                &preview_tabs.enabled
1541                            } else {
1542                                &None
1543                            }
1544                        },
1545                        pick_mut: |settings_content| {
1546                            &mut settings_content
1547                                .preview_tabs
1548                                .get_or_insert_default()
1549                                .enabled
1550                        },
1551                    }),
1552                    metadata: None,
1553                }),
1554                SettingsPageItem::SettingItem(SettingItem {
1555                    title: "Enable Preview From File Finder",
1556                    description: "Whether to open tabs in preview mode when selected from the file finder",
1557                    field: Box::new(SettingField {
1558                        pick: |settings_content| {
1559                            if let Some(preview_tabs) = &settings_content.preview_tabs {
1560                                &preview_tabs.enable_preview_from_file_finder
1561                            } else {
1562                                &None
1563                            }
1564                        },
1565                        pick_mut: |settings_content| {
1566                            &mut settings_content
1567                                .preview_tabs
1568                                .get_or_insert_default()
1569                                .enable_preview_from_file_finder
1570                        },
1571                    }),
1572                    metadata: None,
1573                }),
1574                SettingsPageItem::SettingItem(SettingItem {
1575                    title: "Enable Preview From Code Navigation",
1576                    description: "Whether a preview tab gets replaced when code navigation is used to navigate away from the tab",
1577                    field: Box::new(SettingField {
1578                        pick: |settings_content| {
1579                            if let Some(preview_tabs) = &settings_content.preview_tabs {
1580                                &preview_tabs.enable_preview_from_code_navigation
1581                            } else {
1582                                &None
1583                            }
1584                        },
1585                        pick_mut: |settings_content| {
1586                            &mut settings_content
1587                                .preview_tabs
1588                                .get_or_insert_default()
1589                                .enable_preview_from_code_navigation
1590                        },
1591                    }),
1592                    metadata: None,
1593                }),
1594            ],
1595        },
1596        SettingsPage {
1597            title: "Version Control",
1598            items: vec![
1599                SettingsPageItem::SectionHeader("Git"),
1600                SettingsPageItem::SettingItem(SettingItem {
1601                    title: "Git Gutter",
1602                    description: "Control whether the git gutter is shown",
1603                    field: Box::new(SettingField {
1604                        pick: |settings_content| {
1605                            if let Some(git) = &settings_content.git {
1606                                &git.git_gutter
1607                            } else {
1608                                &None
1609                            }
1610                        },
1611                        pick_mut: |settings_content| {
1612                            &mut settings_content.git.get_or_insert_default().git_gutter
1613                        },
1614                    }),
1615                    metadata: None,
1616                }),
1617                // todo(settings_ui): Figure out the right default for this value in default.json
1618                // SettingsPageItem::SettingItem(SettingItem {
1619                //     title: "Gutter Debounce",
1620                //     description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter",
1621                //     field: Box::new(SettingField {
1622                //         pick: |settings_content| {
1623                //             if let Some(git) = &settings_content.git {
1624                //                 &git.gutter_debounce
1625                //             } else {
1626                //                 &None
1627                //             }
1628                //         },
1629                //         pick_mut: |settings_content| {
1630                //             &mut settings_content.git.get_or_insert_default().gutter_debounce
1631                //         },
1632                //     }),
1633                //     metadata: None,
1634                // }),
1635                SettingsPageItem::SettingItem(SettingItem {
1636                    title: "Inline Blame Enabled",
1637                    description: "Whether or not to show git blame data inline in the currently focused line",
1638                    field: Box::new(SettingField {
1639                        pick: |settings_content| {
1640                            if let Some(git) = &settings_content.git {
1641                                if let Some(inline_blame) = &git.inline_blame {
1642                                    &inline_blame.enabled
1643                                } else {
1644                                    &None
1645                                }
1646                            } else {
1647                                &None
1648                            }
1649                        },
1650                        pick_mut: |settings_content| {
1651                            &mut settings_content
1652                                .git
1653                                .get_or_insert_default()
1654                                .inline_blame
1655                                .get_or_insert_default()
1656                                .enabled
1657                        },
1658                    }),
1659                    metadata: None,
1660                }),
1661                SettingsPageItem::SettingItem(SettingItem {
1662                    title: "Inline Blame Delay",
1663                    description: "The delay after which the inline blame information is shown",
1664                    field: Box::new(SettingField {
1665                        pick: |settings_content| {
1666                            if let Some(git) = &settings_content.git {
1667                                if let Some(inline_blame) = &git.inline_blame {
1668                                    &inline_blame.delay_ms
1669                                } else {
1670                                    &None
1671                                }
1672                            } else {
1673                                &None
1674                            }
1675                        },
1676                        pick_mut: |settings_content| {
1677                            &mut settings_content
1678                                .git
1679                                .get_or_insert_default()
1680                                .inline_blame
1681                                .get_or_insert_default()
1682                                .delay_ms
1683                        },
1684                    }),
1685                    metadata: None,
1686                }),
1687                SettingsPageItem::SettingItem(SettingItem {
1688                    title: "Inline Blame Padding",
1689                    description: "Padding between the end of the source line and the start of the inline blame in columns",
1690                    field: Box::new(SettingField {
1691                        pick: |settings_content| {
1692                            if let Some(git) = &settings_content.git {
1693                                if let Some(inline_blame) = &git.inline_blame {
1694                                    &inline_blame.padding
1695                                } else {
1696                                    &None
1697                                }
1698                            } else {
1699                                &None
1700                            }
1701                        },
1702                        pick_mut: |settings_content| {
1703                            &mut settings_content
1704                                .git
1705                                .get_or_insert_default()
1706                                .inline_blame
1707                                .get_or_insert_default()
1708                                .padding
1709                        },
1710                    }),
1711                    metadata: None,
1712                }),
1713                SettingsPageItem::SettingItem(SettingItem {
1714                    title: "Inline Blame Min Column",
1715                    description: "The minimum column number to show the inline blame information at",
1716                    field: Box::new(SettingField {
1717                        pick: |settings_content| {
1718                            if let Some(git) = &settings_content.git {
1719                                if let Some(inline_blame) = &git.inline_blame {
1720                                    &inline_blame.min_column
1721                                } else {
1722                                    &None
1723                                }
1724                            } else {
1725                                &None
1726                            }
1727                        },
1728                        pick_mut: |settings_content| {
1729                            &mut settings_content
1730                                .git
1731                                .get_or_insert_default()
1732                                .inline_blame
1733                                .get_or_insert_default()
1734                                .min_column
1735                        },
1736                    }),
1737                    metadata: None,
1738                }),
1739                SettingsPageItem::SettingItem(SettingItem {
1740                    title: "Show Commit Summary",
1741                    description: "Whether to show commit summary as part of the inline blame",
1742                    field: Box::new(SettingField {
1743                        pick: |settings_content| {
1744                            if let Some(git) = &settings_content.git {
1745                                if let Some(inline_blame) = &git.inline_blame {
1746                                    &inline_blame.show_commit_summary
1747                                } else {
1748                                    &None
1749                                }
1750                            } else {
1751                                &None
1752                            }
1753                        },
1754                        pick_mut: |settings_content| {
1755                            &mut settings_content
1756                                .git
1757                                .get_or_insert_default()
1758                                .inline_blame
1759                                .get_or_insert_default()
1760                                .show_commit_summary
1761                        },
1762                    }),
1763                    metadata: None,
1764                }),
1765                SettingsPageItem::SettingItem(SettingItem {
1766                    title: "Show Avatar",
1767                    description: "Whether to show the avatar of the author of the commit",
1768                    field: Box::new(SettingField {
1769                        pick: |settings_content| {
1770                            if let Some(git) = &settings_content.git {
1771                                if let Some(blame) = &git.blame {
1772                                    &blame.show_avatar
1773                                } else {
1774                                    &None
1775                                }
1776                            } else {
1777                                &None
1778                            }
1779                        },
1780                        pick_mut: |settings_content| {
1781                            &mut settings_content
1782                                .git
1783                                .get_or_insert_default()
1784                                .blame
1785                                .get_or_insert_default()
1786                                .show_avatar
1787                        },
1788                    }),
1789                    metadata: None,
1790                }),
1791                SettingsPageItem::SettingItem(SettingItem {
1792                    title: "Show Author Name In Branch Picker",
1793                    description: "Whether to show author name as part of the commit information in branch picker",
1794                    field: Box::new(SettingField {
1795                        pick: |settings_content| {
1796                            if let Some(git) = &settings_content.git {
1797                                if let Some(branch_picker) = &git.branch_picker {
1798                                    &branch_picker.show_author_name
1799                                } else {
1800                                    &None
1801                                }
1802                            } else {
1803                                &None
1804                            }
1805                        },
1806                        pick_mut: |settings_content| {
1807                            &mut settings_content
1808                                .git
1809                                .get_or_insert_default()
1810                                .branch_picker
1811                                .get_or_insert_default()
1812                                .show_author_name
1813                        },
1814                    }),
1815                    metadata: None,
1816                }),
1817                SettingsPageItem::SettingItem(SettingItem {
1818                    title: "Hunk Style",
1819                    description: "How git hunks are displayed visually in the editor",
1820                    field: Box::new(SettingField {
1821                        pick: |settings_content| {
1822                            if let Some(git) = &settings_content.git {
1823                                &git.hunk_style
1824                            } else {
1825                                &None
1826                            }
1827                        },
1828                        pick_mut: |settings_content| {
1829                            &mut settings_content.git.get_or_insert_default().hunk_style
1830                        },
1831                    }),
1832                    metadata: None,
1833                }),
1834            ],
1835        },
1836        SettingsPage {
1837            title: "System & Network",
1838            items: vec![
1839                SettingsPageItem::SectionHeader("Network"),
1840                // todo(settings_ui): Proxy needs a default
1841                // SettingsPageItem::SettingItem(SettingItem {
1842                //     title: "Proxy",
1843                //     description: "The proxy to use for network requests",
1844                //     field: Box::new(SettingField {
1845                //         pick: |settings_content| &settings_content.proxy,
1846                //         pick_mut: |settings_content| &mut settings_content.proxy,
1847                //     }),
1848                //     metadata: Some(Box::new(SettingsFieldMetadata {
1849                //         placeholder: Some("socks5h://localhost:10808"),
1850                //     })),
1851                // }),
1852                SettingsPageItem::SettingItem(SettingItem {
1853                    title: "Server URL",
1854                    description: "The URL of the Zed server to connect to",
1855                    field: Box::new(SettingField {
1856                        pick: |settings_content| &settings_content.server_url,
1857                        pick_mut: |settings_content| &mut settings_content.server_url,
1858                    }),
1859                    metadata: Some(Box::new(SettingsFieldMetadata {
1860                        placeholder: Some("https://zed.dev"),
1861                    })),
1862                }),
1863                SettingsPageItem::SectionHeader("System"),
1864                SettingsPageItem::SettingItem(SettingItem {
1865                    title: "Auto Update",
1866                    description: "Whether or not to automatically check for updates",
1867                    field: Box::new(SettingField {
1868                        pick: |settings_content| &settings_content.auto_update,
1869                        pick_mut: |settings_content| &mut settings_content.auto_update,
1870                    }),
1871                    metadata: None,
1872                }),
1873            ],
1874        },
1875        SettingsPage {
1876            title: "Diagnostics & Errors",
1877            items: vec![
1878                SettingsPageItem::SectionHeader("Display"),
1879                SettingsPageItem::SettingItem(SettingItem {
1880                    title: "Diagnostics Button",
1881                    description: "Whether to show the project diagnostics button in the status bar",
1882                    field: Box::new(SettingField {
1883                        pick: |settings_content| {
1884                            if let Some(diagnostics) = &settings_content.diagnostics {
1885                                &diagnostics.button
1886                            } else {
1887                                &None
1888                            }
1889                        },
1890                        pick_mut: |settings_content| {
1891                            &mut settings_content.diagnostics.get_or_insert_default().button
1892                        },
1893                    }),
1894                    metadata: None,
1895                }),
1896                SettingsPageItem::SectionHeader("Filtering"),
1897                SettingsPageItem::SettingItem(SettingItem {
1898                    title: "Max Severity",
1899                    description: "Which level to use to filter out diagnostics displayed in the editor",
1900                    field: Box::new(SettingField {
1901                        pick: |settings_content| &settings_content.editor.diagnostics_max_severity,
1902                        pick_mut: |settings_content| {
1903                            &mut settings_content.editor.diagnostics_max_severity
1904                        },
1905                    }),
1906                    metadata: None,
1907                }),
1908                SettingsPageItem::SettingItem(SettingItem {
1909                    title: "Include Warnings",
1910                    description: "Whether to show warnings or not by default",
1911                    field: Box::new(SettingField {
1912                        pick: |settings_content| {
1913                            if let Some(diagnostics) = &settings_content.diagnostics {
1914                                &diagnostics.include_warnings
1915                            } else {
1916                                &None
1917                            }
1918                        },
1919                        pick_mut: |settings_content| {
1920                            &mut settings_content
1921                                .diagnostics
1922                                .get_or_insert_default()
1923                                .include_warnings
1924                        },
1925                    }),
1926                    metadata: None,
1927                }),
1928                SettingsPageItem::SectionHeader("Inline"),
1929                SettingsPageItem::SettingItem(SettingItem {
1930                    title: "Inline Diagnostics Enabled",
1931                    description: "Whether to show diagnostics inline or not",
1932                    field: Box::new(SettingField {
1933                        pick: |settings_content| {
1934                            if let Some(diagnostics) = &settings_content.diagnostics {
1935                                if let Some(inline) = &diagnostics.inline {
1936                                    &inline.enabled
1937                                } else {
1938                                    &None
1939                                }
1940                            } else {
1941                                &None
1942                            }
1943                        },
1944                        pick_mut: |settings_content| {
1945                            &mut settings_content
1946                                .diagnostics
1947                                .get_or_insert_default()
1948                                .inline
1949                                .get_or_insert_default()
1950                                .enabled
1951                        },
1952                    }),
1953                    metadata: None,
1954                }),
1955                // todo(settings_ui): Needs numeric stepper
1956                SettingsPageItem::SettingItem(SettingItem {
1957                    title: "Inline Update Debounce",
1958                    description: "The delay in milliseconds to show inline diagnostics after the last diagnostic update",
1959                    field: Box::new(SettingField {
1960                        pick: |settings_content| {
1961                            if let Some(diagnostics) = &settings_content.diagnostics {
1962                                if let Some(inline) = &diagnostics.inline {
1963                                    &inline.update_debounce_ms
1964                                } else {
1965                                    &None
1966                                }
1967                            } else {
1968                                &None
1969                            }
1970                        },
1971                        pick_mut: |settings_content| {
1972                            &mut settings_content
1973                                .diagnostics
1974                                .get_or_insert_default()
1975                                .inline
1976                                .get_or_insert_default()
1977                                .update_debounce_ms
1978                        },
1979                    }),
1980                    metadata: None,
1981                }),
1982                // todo(settings_ui): Needs numeric stepper
1983                SettingsPageItem::SettingItem(SettingItem {
1984                    title: "Inline Padding",
1985                    description: "The amount of padding between the end of the source line and the start of the inline diagnostic",
1986                    field: Box::new(SettingField {
1987                        pick: |settings_content| {
1988                            if let Some(diagnostics) = &settings_content.diagnostics {
1989                                if let Some(inline) = &diagnostics.inline {
1990                                    &inline.padding
1991                                } else {
1992                                    &None
1993                                }
1994                            } else {
1995                                &None
1996                            }
1997                        },
1998                        pick_mut: |settings_content| {
1999                            &mut settings_content
2000                                .diagnostics
2001                                .get_or_insert_default()
2002                                .inline
2003                                .get_or_insert_default()
2004                                .padding
2005                        },
2006                    }),
2007                    metadata: None,
2008                }),
2009                // todo(settings_ui): Needs numeric stepper
2010                SettingsPageItem::SettingItem(SettingItem {
2011                    title: "Inline Min Column",
2012                    description: "The minimum column to display inline diagnostics",
2013                    field: Box::new(SettingField {
2014                        pick: |settings_content| {
2015                            if let Some(diagnostics) = &settings_content.diagnostics {
2016                                if let Some(inline) = &diagnostics.inline {
2017                                    &inline.min_column
2018                                } else {
2019                                    &None
2020                                }
2021                            } else {
2022                                &None
2023                            }
2024                        },
2025                        pick_mut: |settings_content| {
2026                            &mut settings_content
2027                                .diagnostics
2028                                .get_or_insert_default()
2029                                .inline
2030                                .get_or_insert_default()
2031                                .min_column
2032                        },
2033                    }),
2034                    metadata: None,
2035                }),
2036                SettingsPageItem::SectionHeader("Performance"),
2037                SettingsPageItem::SettingItem(SettingItem {
2038                    title: "LSP Pull Diagnostics Enabled",
2039                    description: "Whether to pull for diagnostics or not",
2040                    field: Box::new(SettingField {
2041                        pick: |settings_content| {
2042                            if let Some(diagnostics) = &settings_content.diagnostics {
2043                                if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
2044                                    &lsp_pull.enabled
2045                                } else {
2046                                    &None
2047                                }
2048                            } else {
2049                                &None
2050                            }
2051                        },
2052                        pick_mut: |settings_content| {
2053                            &mut settings_content
2054                                .diagnostics
2055                                .get_or_insert_default()
2056                                .lsp_pull_diagnostics
2057                                .get_or_insert_default()
2058                                .enabled
2059                        },
2060                    }),
2061                    metadata: None,
2062                }),
2063                // todo(settings_ui): Needs unit
2064                SettingsPageItem::SettingItem(SettingItem {
2065                    title: "LSP Pull Debounce",
2066                    description: "Minimum time to wait before pulling diagnostics from the language server(s)",
2067                    field: Box::new(SettingField {
2068                        pick: |settings_content| {
2069                            if let Some(diagnostics) = &settings_content.diagnostics {
2070                                if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
2071                                    &lsp_pull.debounce_ms
2072                                } else {
2073                                    &None
2074                                }
2075                            } else {
2076                                &None
2077                            }
2078                        },
2079                        pick_mut: |settings_content| {
2080                            &mut settings_content
2081                                .diagnostics
2082                                .get_or_insert_default()
2083                                .lsp_pull_diagnostics
2084                                .get_or_insert_default()
2085                                .debounce_ms
2086                        },
2087                    }),
2088                    metadata: None,
2089                }),
2090            ],
2091        },
2092        SettingsPage {
2093            title: "Collaboration",
2094            items: vec![
2095                SettingsPageItem::SectionHeader("Calls"),
2096                SettingsPageItem::SettingItem(SettingItem {
2097                    title: "Mute On Join",
2098                    description: "Whether the microphone should be muted when joining a channel or a call",
2099                    field: Box::new(SettingField {
2100                        pick: |settings_content| {
2101                            if let Some(calls) = &settings_content.calls {
2102                                &calls.mute_on_join
2103                            } else {
2104                                &None
2105                            }
2106                        },
2107                        pick_mut: |settings_content| {
2108                            &mut settings_content.calls.get_or_insert_default().mute_on_join
2109                        },
2110                    }),
2111                    metadata: None,
2112                }),
2113                SettingsPageItem::SettingItem(SettingItem {
2114                    title: "Share On Join",
2115                    description: "Whether your current project should be shared when joining an empty channel",
2116                    field: Box::new(SettingField {
2117                        pick: |settings_content| {
2118                            if let Some(calls) = &settings_content.calls {
2119                                &calls.share_on_join
2120                            } else {
2121                                &None
2122                            }
2123                        },
2124                        pick_mut: |settings_content| {
2125                            &mut settings_content.calls.get_or_insert_default().share_on_join
2126                        },
2127                    }),
2128                    metadata: None,
2129                }),
2130                SettingsPageItem::SectionHeader("Panel"),
2131                SettingsPageItem::SettingItem(SettingItem {
2132                    title: "Collaboration Panel Button",
2133                    description: "Whether to show the collaboration panel button in the status bar",
2134                    field: Box::new(SettingField {
2135                        pick: |settings_content| {
2136                            if let Some(collab) = &settings_content.collaboration_panel {
2137                                &collab.button
2138                            } else {
2139                                &None
2140                            }
2141                        },
2142                        pick_mut: |settings_content| {
2143                            &mut settings_content
2144                                .collaboration_panel
2145                                .get_or_insert_default()
2146                                .button
2147                        },
2148                    }),
2149                    metadata: None,
2150                }),
2151                SettingsPageItem::SectionHeader("Experimental"),
2152                SettingsPageItem::SettingItem(SettingItem {
2153                    title: "Rodio Audio",
2154                    description: "Opt into the new audio system",
2155                    field: Box::new(SettingField {
2156                        pick: |settings_content| {
2157                            if let Some(audio) = &settings_content.audio {
2158                                &audio.rodio_audio
2159                            } else {
2160                                &None
2161                            }
2162                        },
2163                        pick_mut: |settings_content| {
2164                            &mut settings_content.audio.get_or_insert_default().rodio_audio
2165                        },
2166                    }),
2167                    metadata: None,
2168                }),
2169            ],
2170        },
2171        SettingsPage {
2172            title: "AI",
2173            items: vec![
2174                SettingsPageItem::SectionHeader("General"),
2175                SettingsPageItem::SettingItem(SettingItem {
2176                    title: "Disable AI",
2177                    description: "Whether to disable all AI features in Zed",
2178                    field: Box::new(SettingField {
2179                        pick: |settings_content| &settings_content.disable_ai,
2180                        pick_mut: |settings_content| &mut settings_content.disable_ai,
2181                    }),
2182                    metadata: None,
2183                }),
2184            ],
2185        },
2186    ]
2187}
2188
2189pub(crate) fn project_settings_data() -> Vec<SettingsPage> {
2190    vec![
2191        SettingsPage {
2192            title: "Project",
2193            items: vec![
2194                SettingsPageItem::SectionHeader("Worktree Settings Content"),
2195                SettingsPageItem::SettingItem(SettingItem {
2196                    title: "Project Name",
2197                    description: "The displayed name of this project. If not set, the root directory name",
2198                    field: Box::new(SettingField {
2199                        pick: |settings_content| &settings_content.project.worktree.project_name,
2200                        pick_mut: |settings_content| {
2201                            &mut settings_content.project.worktree.project_name
2202                        },
2203                    }),
2204                    metadata: Some(Box::new(SettingsFieldMetadata {
2205                        placeholder: Some("A new name"),
2206                    })),
2207                }),
2208            ],
2209        },
2210        SettingsPage {
2211            title: "Appearance & Behavior",
2212            items: vec![
2213                SettingsPageItem::SectionHeader("Guides"),
2214                SettingsPageItem::SettingItem(SettingItem {
2215                    title: "Show Wrap Guides",
2216                    description: "Whether to show wrap guides (vertical rulers)",
2217                    field: Box::new(SettingField {
2218                        pick: |settings_content| {
2219                            &settings_content
2220                                .project
2221                                .all_languages
2222                                .defaults
2223                                .show_wrap_guides
2224                        },
2225                        pick_mut: |settings_content| {
2226                            &mut settings_content
2227                                .project
2228                                .all_languages
2229                                .defaults
2230                                .show_wrap_guides
2231                        },
2232                    }),
2233                    metadata: None,
2234                }),
2235                // todo(settings_ui): This needs a custom component
2236                // SettingsPageItem::SettingItem(SettingItem {
2237                //     title: "Wrap Guides",
2238                //     description: "Character counts at which to show wrap guides",
2239                //     field: Box::new(SettingField {
2240                //         pick: |settings_content| {
2241                //             &settings_content
2242                //                 .project
2243                //                 .all_languages
2244                //                 .defaults
2245                //                 .wrap_guides
2246                //         },
2247                //         pick_mut: |settings_content| {
2248                //             &mut settings_content
2249                //                 .project
2250                //                 .all_languages
2251                //                 .defaults
2252                //                 .wrap_guides
2253                //         },
2254                //     }),
2255                //     metadata: None,
2256                // }),
2257                SettingsPageItem::SectionHeader("Whitespace"),
2258                SettingsPageItem::SettingItem(SettingItem {
2259                    title: "Show Whitespace",
2260                    description: "Whether to show tabs and spaces",
2261                    field: Box::new(SettingField {
2262                        pick: |settings_content| {
2263                            &settings_content
2264                                .project
2265                                .all_languages
2266                                .defaults
2267                                .show_whitespaces
2268                        },
2269                        pick_mut: |settings_content| {
2270                            &mut settings_content
2271                                .project
2272                                .all_languages
2273                                .defaults
2274                                .show_whitespaces
2275                        },
2276                    }),
2277                    metadata: None,
2278                }),
2279            ],
2280        },
2281        SettingsPage {
2282            title: "Editing",
2283            items: vec![
2284                SettingsPageItem::SectionHeader("Indentation"),
2285                // todo(settings_ui): Needs numeric stepper
2286                // SettingsPageItem::SettingItem(SettingItem {
2287                //     title: "Tab Size",
2288                //     description: "How many columns a tab should occupy",
2289                //     field: Box::new(SettingField {
2290                //         pick: |settings_content| &settings_content.project.all_languages.defaults.tab_size,
2291                //         pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.tab_size,
2292                //     }),
2293                //     metadata: None,
2294                // }),
2295                SettingsPageItem::SettingItem(SettingItem {
2296                    title: "Hard Tabs",
2297                    description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
2298                    field: Box::new(SettingField {
2299                        pick: |settings_content| {
2300                            &settings_content.project.all_languages.defaults.hard_tabs
2301                        },
2302                        pick_mut: |settings_content| {
2303                            &mut settings_content.project.all_languages.defaults.hard_tabs
2304                        },
2305                    }),
2306                    metadata: None,
2307                }),
2308                SettingsPageItem::SettingItem(SettingItem {
2309                    title: "Auto Indent",
2310                    description: "Whether indentation should be adjusted based on the context whilst typing",
2311                    field: Box::new(SettingField {
2312                        pick: |settings_content| {
2313                            &settings_content.project.all_languages.defaults.auto_indent
2314                        },
2315                        pick_mut: |settings_content| {
2316                            &mut settings_content.project.all_languages.defaults.auto_indent
2317                        },
2318                    }),
2319                    metadata: None,
2320                }),
2321                SettingsPageItem::SettingItem(SettingItem {
2322                    title: "Auto Indent On Paste",
2323                    description: "Whether indentation of pasted content should be adjusted based on the context",
2324                    field: Box::new(SettingField {
2325                        pick: |settings_content| {
2326                            &settings_content
2327                                .project
2328                                .all_languages
2329                                .defaults
2330                                .auto_indent_on_paste
2331                        },
2332                        pick_mut: |settings_content| {
2333                            &mut settings_content
2334                                .project
2335                                .all_languages
2336                                .defaults
2337                                .auto_indent_on_paste
2338                        },
2339                    }),
2340                    metadata: None,
2341                }),
2342                SettingsPageItem::SectionHeader("Wrapping"),
2343                // todo(settings_ui): Needs numeric stepper
2344                // SettingsPageItem::SettingItem(SettingItem {
2345                //     title: "Preferred Line Length",
2346                //     description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
2347                //     field: Box::new(SettingField {
2348                //         pick: |settings_content| &settings_content.project.all_languages.defaults.preferred_line_length,
2349                //         pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.preferred_line_length,
2350                //     }),
2351                //     metadata: None,
2352                // }),
2353                SettingsPageItem::SettingItem(SettingItem {
2354                    title: "Soft Wrap",
2355                    description: "How to soft-wrap long lines of text",
2356                    field: Box::new(SettingField {
2357                        pick: |settings_content| {
2358                            &settings_content.project.all_languages.defaults.soft_wrap
2359                        },
2360                        pick_mut: |settings_content| {
2361                            &mut settings_content.project.all_languages.defaults.soft_wrap
2362                        },
2363                    }),
2364                    metadata: None,
2365                }),
2366                SettingsPageItem::SectionHeader("Auto Actions"),
2367                SettingsPageItem::SettingItem(SettingItem {
2368                    title: "Use Autoclose",
2369                    description: "Whether to automatically type closing characters for you",
2370                    field: Box::new(SettingField {
2371                        pick: |settings_content| {
2372                            &settings_content
2373                                .project
2374                                .all_languages
2375                                .defaults
2376                                .use_autoclose
2377                        },
2378                        pick_mut: |settings_content| {
2379                            &mut settings_content
2380                                .project
2381                                .all_languages
2382                                .defaults
2383                                .use_autoclose
2384                        },
2385                    }),
2386                    metadata: None,
2387                }),
2388                SettingsPageItem::SettingItem(SettingItem {
2389                    title: "Use Auto Surround",
2390                    description: "Whether to automatically surround text with characters for you",
2391                    field: Box::new(SettingField {
2392                        pick: |settings_content| {
2393                            &settings_content
2394                                .project
2395                                .all_languages
2396                                .defaults
2397                                .use_auto_surround
2398                        },
2399                        pick_mut: |settings_content| {
2400                            &mut settings_content
2401                                .project
2402                                .all_languages
2403                                .defaults
2404                                .use_auto_surround
2405                        },
2406                    }),
2407                    metadata: None,
2408                }),
2409                SettingsPageItem::SettingItem(SettingItem {
2410                    title: "Use On Type Format",
2411                    description: "Whether to use additional LSP queries to format the code after every trigger symbol input",
2412                    field: Box::new(SettingField {
2413                        pick: |settings_content| {
2414                            &settings_content
2415                                .project
2416                                .all_languages
2417                                .defaults
2418                                .use_on_type_format
2419                        },
2420                        pick_mut: |settings_content| {
2421                            &mut settings_content
2422                                .project
2423                                .all_languages
2424                                .defaults
2425                                .use_on_type_format
2426                        },
2427                    }),
2428                    metadata: None,
2429                }),
2430                SettingsPageItem::SettingItem(SettingItem {
2431                    title: "Always Treat Brackets As Autoclosed",
2432                    description: "Controls how the editor handles the autoclosed characters",
2433                    field: Box::new(SettingField {
2434                        pick: |settings_content| {
2435                            &settings_content
2436                                .project
2437                                .all_languages
2438                                .defaults
2439                                .always_treat_brackets_as_autoclosed
2440                        },
2441                        pick_mut: |settings_content| {
2442                            &mut settings_content
2443                                .project
2444                                .all_languages
2445                                .defaults
2446                                .always_treat_brackets_as_autoclosed
2447                        },
2448                    }),
2449                    metadata: None,
2450                }),
2451                SettingsPageItem::SectionHeader("Formatting"),
2452                SettingsPageItem::SettingItem(SettingItem {
2453                    title: "Remove Trailing Whitespace On Save",
2454                    description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
2455                    field: Box::new(SettingField {
2456                        pick: |settings_content| {
2457                            &settings_content
2458                                .project
2459                                .all_languages
2460                                .defaults
2461                                .remove_trailing_whitespace_on_save
2462                        },
2463                        pick_mut: |settings_content| {
2464                            &mut settings_content
2465                                .project
2466                                .all_languages
2467                                .defaults
2468                                .remove_trailing_whitespace_on_save
2469                        },
2470                    }),
2471                    metadata: None,
2472                }),
2473                SettingsPageItem::SettingItem(SettingItem {
2474                    title: "Ensure Final Newline On Save",
2475                    description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
2476                    field: Box::new(SettingField {
2477                        pick: |settings_content| {
2478                            &settings_content
2479                                .project
2480                                .all_languages
2481                                .defaults
2482                                .ensure_final_newline_on_save
2483                        },
2484                        pick_mut: |settings_content| {
2485                            &mut settings_content
2486                                .project
2487                                .all_languages
2488                                .defaults
2489                                .ensure_final_newline_on_save
2490                        },
2491                    }),
2492                    metadata: None,
2493                }),
2494                SettingsPageItem::SettingItem(SettingItem {
2495                    title: "Extend Comment On Newline",
2496                    description: "Whether to start a new line with a comment when a previous line is a comment as well",
2497                    field: Box::new(SettingField {
2498                        pick: |settings_content| {
2499                            &settings_content
2500                                .project
2501                                .all_languages
2502                                .defaults
2503                                .extend_comment_on_newline
2504                        },
2505                        pick_mut: |settings_content| {
2506                            &mut settings_content
2507                                .project
2508                                .all_languages
2509                                .defaults
2510                                .extend_comment_on_newline
2511                        },
2512                    }),
2513                    metadata: None,
2514                }),
2515                SettingsPageItem::SectionHeader("Completions"),
2516                SettingsPageItem::SettingItem(SettingItem {
2517                    title: "Show Completions On Input",
2518                    description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
2519                    field: Box::new(SettingField {
2520                        pick: |settings_content| {
2521                            &settings_content
2522                                .project
2523                                .all_languages
2524                                .defaults
2525                                .show_completions_on_input
2526                        },
2527                        pick_mut: |settings_content| {
2528                            &mut settings_content
2529                                .project
2530                                .all_languages
2531                                .defaults
2532                                .show_completions_on_input
2533                        },
2534                    }),
2535                    metadata: None,
2536                }),
2537                SettingsPageItem::SettingItem(SettingItem {
2538                    title: "Show Completion Documentation",
2539                    description: "Whether to display inline and alongside documentation for items in the completions menu",
2540                    field: Box::new(SettingField {
2541                        pick: |settings_content| {
2542                            &settings_content
2543                                .project
2544                                .all_languages
2545                                .defaults
2546                                .show_completion_documentation
2547                        },
2548                        pick_mut: |settings_content| {
2549                            &mut settings_content
2550                                .project
2551                                .all_languages
2552                                .defaults
2553                                .show_completion_documentation
2554                        },
2555                    }),
2556                    metadata: None,
2557                }),
2558            ],
2559        },
2560    ]
2561}