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