page_data.rs

   1use settings::{LanguageSettingsContent, SettingsContent};
   2use std::sync::Arc;
   3use ui::{IntoElement, SharedString};
   4
   5use crate::{
   6    SettingField, SettingItem, SettingsFieldMetadata, SettingsPage, SettingsPageItem, SubPageLink,
   7    sub_page_stack,
   8};
   9
  10pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
  11    vec![
  12        SettingsPage {
  13            title: "General Page",
  14            items: vec![
  15                SettingsPageItem::SectionHeader("General"),
  16                SettingsPageItem::SettingItem(SettingItem {
  17                    title: "Confirm Quit",
  18                    description: "Whether to confirm before quitting Zed",
  19                    field: Box::new(SettingField {
  20                        pick: |settings_content| &settings_content.workspace.confirm_quit,
  21                        pick_mut: |settings_content| &mut settings_content.workspace.confirm_quit,
  22                    }),
  23                    metadata: None,
  24                }),
  25                SettingsPageItem::SettingItem(SettingItem {
  26                    title: "Restore On Startup",
  27                    description: "Whether to restore previous session when opening Zed",
  28                    field: Box::new(SettingField {
  29                        pick: |settings_content| &settings_content.workspace.restore_on_startup,
  30                        pick_mut: |settings_content| {
  31                            &mut settings_content.workspace.restore_on_startup
  32                        },
  33                    }),
  34                    metadata: None,
  35                }),
  36                SettingsPageItem::SettingItem(SettingItem {
  37                    title: "Restore File State",
  38                    description: "Whether to restore previous file state when reopening",
  39                    field: Box::new(SettingField {
  40                        pick: |settings_content| &settings_content.workspace.restore_on_file_reopen,
  41                        pick_mut: |settings_content| {
  42                            &mut settings_content.workspace.restore_on_file_reopen
  43                        },
  44                    }),
  45                    metadata: None,
  46                }),
  47                SettingsPageItem::SettingItem(SettingItem {
  48                    title: "Close on File Delete",
  49                    description: "Whether to automatically close files that have been deleted",
  50                    field: Box::new(SettingField {
  51                        pick: |settings_content| &settings_content.workspace.close_on_file_delete,
  52                        pick_mut: |settings_content| {
  53                            &mut settings_content.workspace.close_on_file_delete
  54                        },
  55                    }),
  56                    metadata: None,
  57                }),
  58                SettingsPageItem::SettingItem(SettingItem {
  59                    title: "When Closing With No Tabs",
  60                    description: "What to do when using 'close active item' with no tabs",
  61                    field: Box::new(SettingField {
  62                        pick: |settings_content| {
  63                            &settings_content.workspace.when_closing_with_no_tabs
  64                        },
  65                        pick_mut: |settings_content| {
  66                            &mut settings_content.workspace.when_closing_with_no_tabs
  67                        },
  68                    }),
  69                    metadata: None,
  70                }),
  71                SettingsPageItem::SettingItem(SettingItem {
  72                    title: "On Last Window Closed",
  73                    description: "What to do when the last window is closed",
  74                    field: Box::new(SettingField {
  75                        pick: |settings_content| &settings_content.workspace.on_last_window_closed,
  76                        pick_mut: |settings_content| {
  77                            &mut settings_content.workspace.on_last_window_closed
  78                        },
  79                    }),
  80                    metadata: None,
  81                }),
  82                SettingsPageItem::SettingItem(SettingItem {
  83                    title: "Use System Path Prompts",
  84                    description: "Whether to use system dialogs for Open and Save As",
  85                    field: Box::new(SettingField {
  86                        pick: |settings_content| {
  87                            &settings_content.workspace.use_system_path_prompts
  88                        },
  89                        pick_mut: |settings_content| {
  90                            &mut settings_content.workspace.use_system_path_prompts
  91                        },
  92                    }),
  93                    metadata: None,
  94                }),
  95                SettingsPageItem::SettingItem(SettingItem {
  96                    title: "Use System Prompts",
  97                    description: "Whether to use system prompts for confirmations",
  98                    field: Box::new(SettingField {
  99                        pick: |settings_content| &settings_content.workspace.use_system_prompts,
 100                        pick_mut: |settings_content| {
 101                            &mut settings_content.workspace.use_system_prompts
 102                        },
 103                    }),
 104                    metadata: None,
 105                }),
 106                SettingsPageItem::SectionHeader("Scoped Settings"),
 107                // todo(settings_ui): Implement another setting item type that just shows an edit in settings.json
 108                // SettingsPageItem::SettingItem(SettingItem {
 109                //     title: "Preview Channel",
 110                //     description: "Which settings should be activated only in Preview build of Zed",
 111                //     field: Box::new(SettingField {
 112                //         pick: |settings_content| &settings_content.workspace.use_system_prompts,
 113                //         pick_mut: |settings_content| {
 114                //             &mut settings_content.workspace.use_system_prompts
 115                //         },
 116                //     }),
 117                //     metadata: None,
 118                // }),
 119                // SettingsPageItem::SettingItem(SettingItem {
 120                //     title: "Settings Profiles",
 121                //     description: "Any number of settings profiles that are temporarily applied on top of your existing user settings.",
 122                //     field: Box::new(SettingField {
 123                //         pick: |settings_content| &settings_content.workspace.use_system_prompts,
 124                //         pick_mut: |settings_content| {
 125                //             &mut settings_content.workspace.use_system_prompts
 126                //         },
 127                //     }),
 128                //     metadata: None,
 129                // }),
 130                SettingsPageItem::SectionHeader("Privacy"),
 131                SettingsPageItem::SettingItem(SettingItem {
 132                    title: "Telemetry Diagnostics",
 133                    description: "Send debug info like crash reports.",
 134                    field: Box::new(SettingField {
 135                        pick: |settings_content| {
 136                            if let Some(telemetry) = &settings_content.telemetry {
 137                                &telemetry.diagnostics
 138                            } else {
 139                                &None
 140                            }
 141                        },
 142                        pick_mut: |settings_content| {
 143                            &mut settings_content
 144                                .telemetry
 145                                .get_or_insert_default()
 146                                .diagnostics
 147                        },
 148                    }),
 149                    metadata: None,
 150                }),
 151                SettingsPageItem::SettingItem(SettingItem {
 152                    title: "Telemetry Metrics",
 153                    description: "Send anonymized usage data like what languages you're using Zed with.",
 154                    field: Box::new(SettingField {
 155                        pick: |settings_content| {
 156                            if let Some(telemetry) = &settings_content.telemetry {
 157                                &telemetry.metrics
 158                            } else {
 159                                &None
 160                            }
 161                        },
 162                        pick_mut: |settings_content| {
 163                            &mut settings_content.telemetry.get_or_insert_default().metrics
 164                        },
 165                    }),
 166                    metadata: None,
 167                }),
 168            ],
 169        },
 170        SettingsPage {
 171            title: "Appearance & Behavior",
 172            items: vec![
 173                SettingsPageItem::SectionHeader("Theme"),
 174                // todo(settings_ui): Figure out how we want to add these
 175                // SettingsPageItem::SettingItem(SettingItem {
 176                //     title: "Theme Mode",
 177                //     description: "How to select the theme",
 178                //     field: Box::new(SettingField {
 179                //         pick: |settings_content| &settings_content.theme.theme,
 180                //         pick_mut: |settings_content| &mut settings_content.theme.theme,
 181                //     }),
 182                //     metadata: None,
 183                // }),
 184                // SettingsPageItem::SettingItem(SettingItem {
 185                //     title: "Icon Theme",
 186                //     // todo(settings_ui)
 187                //     // This description is misleading because the icon theme is used in more places than the file explorer)
 188                //     description: "Choose the icon theme for file explorer",
 189                //     field: Box::new(SettingField {
 190                //         pick: |settings_content| &settings_content.theme.icon_theme,
 191                //         pick_mut: |settings_content| &mut settings_content.theme.icon_theme,
 192                //     }),
 193                //     metadata: None,
 194                // }),
 195                SettingsPageItem::SectionHeader("Layout"),
 196                SettingsPageItem::SettingItem(SettingItem {
 197                    title: "Bottom Dock Layout",
 198                    description: "Layout mode for the bottom dock",
 199                    field: Box::new(SettingField {
 200                        pick: |settings_content| &settings_content.workspace.bottom_dock_layout,
 201                        pick_mut: |settings_content| {
 202                            &mut settings_content.workspace.bottom_dock_layout
 203                        },
 204                    }),
 205                    metadata: None,
 206                }),
 207                SettingsPageItem::SettingItem(SettingItem {
 208                    title: "Zoomed Padding",
 209                    description: "Whether to show padding for zoomed panels",
 210                    field: Box::new(SettingField {
 211                        pick: |settings_content| &settings_content.workspace.zoomed_padding,
 212                        pick_mut: |settings_content| &mut settings_content.workspace.zoomed_padding,
 213                    }),
 214                    metadata: None,
 215                }),
 216                SettingsPageItem::SettingItem(SettingItem {
 217                    title: "Use System Window Tabs",
 218                    description: "Whether to allow windows to tab together based on the user's tabbing preference (macOS only)",
 219                    field: Box::new(SettingField {
 220                        pick: |settings_content| &settings_content.workspace.use_system_window_tabs,
 221                        pick_mut: |settings_content| {
 222                            &mut settings_content.workspace.use_system_window_tabs
 223                        },
 224                    }),
 225                    metadata: None,
 226                }),
 227                SettingsPageItem::SectionHeader("Fonts"),
 228                SettingsPageItem::SettingItem(SettingItem {
 229                    title: "Buffer Font Family",
 230                    description: "Font family for editor text",
 231                    field: Box::new(SettingField {
 232                        pick: |settings_content| &settings_content.theme.buffer_font_family,
 233                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_family,
 234                    }),
 235                    metadata: None,
 236                }),
 237                SettingsPageItem::SettingItem(SettingItem {
 238                    title: "Buffer Font Size",
 239                    description: "Font size for editor text",
 240                    field: Box::new(SettingField {
 241                        pick: |settings_content| &settings_content.theme.buffer_font_size,
 242                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_size,
 243                    }),
 244                    metadata: None,
 245                }),
 246                SettingsPageItem::SettingItem(SettingItem {
 247                    title: "Buffer Font Weight",
 248                    description: "Font weight for editor text (100-900)",
 249                    field: Box::new(SettingField {
 250                        pick: |settings_content| &settings_content.theme.buffer_font_weight,
 251                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_weight,
 252                    }),
 253                    metadata: None,
 254                }),
 255                // todo(settings_ui): This needs custom ui
 256                // SettingsPageItem::SettingItem(SettingItem {
 257                //     title: "Buffer Line Height",
 258                //     description: "Line height for editor text",
 259                //     field: Box::new(SettingField {
 260                //         pick: |settings_content| &settings_content.theme.buffer_line_height,
 261                //         pick_mut: |settings_content| &mut settings_content.theme.buffer_line_height,
 262                //     }),
 263                //     metadata: None,
 264                // }),
 265                SettingsPageItem::SettingItem(SettingItem {
 266                    title: "UI Font Family",
 267                    description: "Font family for UI elements",
 268                    field: Box::new(SettingField {
 269                        pick: |settings_content| &settings_content.theme.ui_font_family,
 270                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_family,
 271                    }),
 272                    metadata: None,
 273                }),
 274                SettingsPageItem::SettingItem(SettingItem {
 275                    title: "UI Font Size",
 276                    description: "Font size for UI elements",
 277                    field: Box::new(SettingField {
 278                        pick: |settings_content| &settings_content.theme.ui_font_size,
 279                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_size,
 280                    }),
 281                    metadata: None,
 282                }),
 283                SettingsPageItem::SettingItem(SettingItem {
 284                    title: "UI Font Weight",
 285                    description: "Font weight for UI elements (100-900)",
 286                    field: Box::new(SettingField {
 287                        pick: |settings_content| &settings_content.theme.ui_font_weight,
 288                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_weight,
 289                    }),
 290                    metadata: None,
 291                }),
 292                SettingsPageItem::SectionHeader("Keymap"),
 293                SettingsPageItem::SettingItem(SettingItem {
 294                    title: "Base Keymap",
 295                    description: "The name of a base set of key bindings to use",
 296                    field: Box::new(SettingField {
 297                        pick: |settings_content| &settings_content.base_keymap,
 298                        pick_mut: |settings_content| &mut settings_content.base_keymap,
 299                    }),
 300                    metadata: None,
 301                }),
 302                // todo(settings_ui): Vim/Helix Mode should be apart of one type because it's undefined
 303                // behavior to have them both enabled at the same time
 304                SettingsPageItem::SettingItem(SettingItem {
 305                    title: "Vim Mode",
 306                    description: "Whether to enable vim modes and key bindings",
 307                    field: Box::new(SettingField {
 308                        pick: |settings_content| &settings_content.vim_mode,
 309                        pick_mut: |settings_content| &mut settings_content.vim_mode,
 310                    }),
 311                    metadata: None,
 312                }),
 313                SettingsPageItem::SettingItem(SettingItem {
 314                    title: "Helix Mode",
 315                    description: "Whether to enable helix modes and key bindings",
 316                    field: Box::new(SettingField {
 317                        pick: |settings_content| &settings_content.helix_mode,
 318                        pick_mut: |settings_content| &mut settings_content.helix_mode,
 319                    }),
 320                    metadata: None,
 321                }),
 322                SettingsPageItem::SettingItem(SettingItem {
 323                    title: "Multi Cursor Modifier",
 324                    description: "Modifier key for adding multiple cursors",
 325                    field: Box::new(SettingField {
 326                        pick: |settings_content| &settings_content.editor.multi_cursor_modifier,
 327                        pick_mut: |settings_content| {
 328                            &mut settings_content.editor.multi_cursor_modifier
 329                        },
 330                    }),
 331                    metadata: None,
 332                }),
 333                SettingsPageItem::SectionHeader("Cursor"),
 334                SettingsPageItem::SettingItem(SettingItem {
 335                    title: "Cursor Blink",
 336                    description: "Whether the cursor blinks in the editor",
 337                    field: Box::new(SettingField {
 338                        pick: |settings_content| &settings_content.editor.cursor_blink,
 339                        pick_mut: |settings_content| &mut settings_content.editor.cursor_blink,
 340                    }),
 341                    metadata: None,
 342                }),
 343                SettingsPageItem::SettingItem(SettingItem {
 344                    title: "Cursor Shape",
 345                    description: "Cursor shape for the editor",
 346                    field: Box::new(SettingField {
 347                        pick: |settings_content| &settings_content.editor.cursor_shape,
 348                        pick_mut: |settings_content| &mut settings_content.editor.cursor_shape,
 349                    }),
 350                    metadata: None,
 351                }),
 352                SettingsPageItem::SettingItem(SettingItem {
 353                    title: "Hide Mouse",
 354                    description: "When to hide the mouse cursor",
 355                    field: Box::new(SettingField {
 356                        pick: |settings_content| &settings_content.editor.hide_mouse,
 357                        pick_mut: |settings_content| &mut settings_content.editor.hide_mouse,
 358                    }),
 359                    metadata: None,
 360                }),
 361                SettingsPageItem::SectionHeader("Highlighting"),
 362                SettingsPageItem::SettingItem(SettingItem {
 363                    title: "Unnecessary Code Fade",
 364                    description: "How much to fade out unused code (0.0 - 0.9)",
 365                    field: Box::new(SettingField {
 366                        pick: |settings_content| &settings_content.theme.unnecessary_code_fade,
 367                        pick_mut: |settings_content| {
 368                            &mut settings_content.theme.unnecessary_code_fade
 369                        },
 370                    }),
 371                    metadata: None,
 372                }),
 373                SettingsPageItem::SettingItem(SettingItem {
 374                    title: "Current Line Highlight",
 375                    description: "How to highlight the current line",
 376                    field: Box::new(SettingField {
 377                        pick: |settings_content| &settings_content.editor.current_line_highlight,
 378                        pick_mut: |settings_content| {
 379                            &mut settings_content.editor.current_line_highlight
 380                        },
 381                    }),
 382                    metadata: None,
 383                }),
 384                SettingsPageItem::SettingItem(SettingItem {
 385                    title: "Selection Highlight",
 386                    description: "Whether to highlight all occurrences of selected text",
 387                    field: Box::new(SettingField {
 388                        pick: |settings_content| &settings_content.editor.selection_highlight,
 389                        pick_mut: |settings_content| {
 390                            &mut settings_content.editor.selection_highlight
 391                        },
 392                    }),
 393                    metadata: None,
 394                }),
 395                SettingsPageItem::SettingItem(SettingItem {
 396                    title: "Rounded Selection",
 397                    description: "Whether the text selection should have rounded corners",
 398                    field: Box::new(SettingField {
 399                        pick: |settings_content| &settings_content.editor.rounded_selection,
 400                        pick_mut: |settings_content| &mut settings_content.editor.rounded_selection,
 401                    }),
 402                    metadata: None,
 403                }),
 404                SettingsPageItem::SectionHeader("Guides"),
 405                SettingsPageItem::SettingItem(SettingItem {
 406                    title: "Show Wrap Guides",
 407                    description: "Whether to show wrap guides (vertical rulers)",
 408                    field: Box::new(SettingField {
 409                        pick: |settings_content| {
 410                            &settings_content
 411                                .project
 412                                .all_languages
 413                                .defaults
 414                                .show_wrap_guides
 415                        },
 416                        pick_mut: |settings_content| {
 417                            &mut settings_content
 418                                .project
 419                                .all_languages
 420                                .defaults
 421                                .show_wrap_guides
 422                        },
 423                    }),
 424                    metadata: None,
 425                }),
 426                // todo(settings_ui): This needs a custom component
 427                // SettingsPageItem::SettingItem(SettingItem {
 428                //     title: "Wrap Guides",
 429                //     description: "Character counts at which to show wrap guides",
 430                //     field: Box::new(SettingField {
 431                //         pick: |settings_content| {
 432                //             &settings_content
 433                //                 .project
 434                //                 .all_languages
 435                //                 .defaults
 436                //                 .wrap_guides
 437                //         },
 438                //         pick_mut: |settings_content| {
 439                //             &mut settings_content
 440                //                 .project
 441                //                 .all_languages
 442                //                 .defaults
 443                //                 .wrap_guides
 444                //         },
 445                //     }),
 446                //     metadata: None,
 447                // }),
 448                SettingsPageItem::SectionHeader("Whitespace"),
 449                SettingsPageItem::SettingItem(SettingItem {
 450                    title: "Show Whitespace",
 451                    description: "Whether to show tabs and spaces",
 452                    field: Box::new(SettingField {
 453                        pick: |settings_content| {
 454                            &settings_content
 455                                .project
 456                                .all_languages
 457                                .defaults
 458                                .show_whitespaces
 459                        },
 460                        pick_mut: |settings_content| {
 461                            &mut settings_content
 462                                .project
 463                                .all_languages
 464                                .defaults
 465                                .show_whitespaces
 466                        },
 467                    }),
 468                    metadata: None,
 469                }),
 470                SettingsPageItem::SectionHeader("Window"),
 471                // todo(settings_ui): Should we filter by platform?
 472                SettingsPageItem::SettingItem(SettingItem {
 473                    title: "Use System Window Tabs",
 474                    description: "Whether to allow windows to tab together (macOS only)",
 475                    field: Box::new(SettingField {
 476                        pick: |settings_content| &settings_content.workspace.use_system_window_tabs,
 477                        pick_mut: |settings_content| {
 478                            &mut settings_content.workspace.use_system_window_tabs
 479                        },
 480                    }),
 481                    metadata: None,
 482                }),
 483                SettingsPageItem::SectionHeader("Layout"),
 484                SettingsPageItem::SettingItem(SettingItem {
 485                    title: "Zoomed Padding",
 486                    description: "Whether to show padding for zoomed panels",
 487                    field: Box::new(SettingField {
 488                        pick: |settings_content| &settings_content.workspace.zoomed_padding,
 489                        pick_mut: |settings_content| &mut settings_content.workspace.zoomed_padding,
 490                    }),
 491                    metadata: None,
 492                }),
 493                // todo(settings_ui): Needs numeric stepper   option within an option
 494                // SettingsPageItem::SettingItem(SettingItem {
 495                //     title: "Centered Layout Left Padding",
 496                //     description: "Left padding for centered layout",
 497                //     field: Box::new(SettingField {
 498                //         pick: |settings_content| {
 499                //             &settings_content.workspace.centered_layout.left_padding
 500                //         },
 501                //         pick_mut: |settings_content| {
 502                //             &mut settings_content.workspace.centered_layout.left_padding
 503                //         },
 504                //     }),
 505                //     metadata: None,
 506                // }),
 507                // SettingsPageItem::SettingItem(SettingItem {
 508                //     title: "Centered Layout Right Padding",
 509                //     description: "Right padding for centered layout",
 510                //     field: Box::new(SettingField {
 511                //         pick: |settings_content| {
 512                //             if let Some(centered_layout) =
 513                //                 &settings_content.workspace.centered_layout
 514                //             {
 515                //                 &centered_layout.right_padding
 516                //             } else {
 517                //                 &None
 518                //             }
 519                //         },
 520                //         pick_mut: |settings_content| {
 521                //             if let Some(mut centered_layout) =
 522                //                 settings_content.workspace.centered_layout
 523                //             {
 524                //                 &mut centered_layout.right_padding
 525                //             } else {
 526                //                 &mut None
 527                //             }
 528                //         },
 529                //     }),
 530                //     metadata: None,
 531                // }),
 532                SettingsPageItem::SettingItem(SettingItem {
 533                    title: "Bottom Dock Layout",
 534                    description: "Layout mode of the bottom dock",
 535                    field: Box::new(SettingField {
 536                        pick: |settings_content| &settings_content.workspace.bottom_dock_layout,
 537                        pick_mut: |settings_content| {
 538                            &mut settings_content.workspace.bottom_dock_layout
 539                        },
 540                    }),
 541                    metadata: None,
 542                }),
 543            ],
 544        },
 545        SettingsPage {
 546            title: "Editor",
 547            items: vec![
 548                SettingsPageItem::SectionHeader("Indentation"),
 549                // todo(settings_ui): Needs numeric stepper
 550                SettingsPageItem::SettingItem(SettingItem {
 551                    title: "Tab Size",
 552                    description: "How many columns a tab should occupy",
 553                    field: Box::new(SettingField {
 554                        pick: |settings_content| {
 555                            &settings_content.project.all_languages.defaults.tab_size
 556                        },
 557                        pick_mut: |settings_content| {
 558                            &mut settings_content.project.all_languages.defaults.tab_size
 559                        },
 560                    }),
 561                    metadata: None,
 562                }),
 563                SettingsPageItem::SettingItem(SettingItem {
 564                    title: "Hard Tabs",
 565                    description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
 566                    field: Box::new(SettingField {
 567                        pick: |settings_content| {
 568                            &settings_content.project.all_languages.defaults.hard_tabs
 569                        },
 570                        pick_mut: |settings_content| {
 571                            &mut settings_content.project.all_languages.defaults.hard_tabs
 572                        },
 573                    }),
 574                    metadata: None,
 575                }),
 576                SettingsPageItem::SettingItem(SettingItem {
 577                    title: "Auto Indent",
 578                    description: "Whether indentation should be adjusted based on the context whilst typing",
 579                    field: Box::new(SettingField {
 580                        pick: |settings_content| {
 581                            &settings_content.project.all_languages.defaults.auto_indent
 582                        },
 583                        pick_mut: |settings_content| {
 584                            &mut settings_content.project.all_languages.defaults.auto_indent
 585                        },
 586                    }),
 587                    metadata: None,
 588                }),
 589                SettingsPageItem::SettingItem(SettingItem {
 590                    title: "Auto Indent On Paste",
 591                    description: "Whether indentation of pasted content should be adjusted based on the context",
 592                    field: Box::new(SettingField {
 593                        pick: |settings_content| {
 594                            &settings_content
 595                                .project
 596                                .all_languages
 597                                .defaults
 598                                .auto_indent_on_paste
 599                        },
 600                        pick_mut: |settings_content| {
 601                            &mut settings_content
 602                                .project
 603                                .all_languages
 604                                .defaults
 605                                .auto_indent_on_paste
 606                        },
 607                    }),
 608                    metadata: None,
 609                }),
 610                SettingsPageItem::SectionHeader("Wrapping"),
 611                // todo(settings_ui): Needs numeric stepper
 612                // SettingsPageItem::SettingItem(SettingItem {
 613                //     title: "Preferred Line Length",
 614                //     description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
 615                //     field: Box::new(SettingField {
 616                //         pick: |settings_content| &settings_content.project.all_languages.defaults.preferred_line_length,
 617                //         pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.preferred_line_length,
 618                //     }),
 619                //     metadata: None,
 620                // }),
 621                SettingsPageItem::SettingItem(SettingItem {
 622                    title: "Soft Wrap",
 623                    description: "How to soft-wrap long lines of text",
 624                    field: Box::new(SettingField {
 625                        pick: |settings_content| {
 626                            &settings_content.project.all_languages.defaults.soft_wrap
 627                        },
 628                        pick_mut: |settings_content| {
 629                            &mut settings_content.project.all_languages.defaults.soft_wrap
 630                        },
 631                    }),
 632                    metadata: None,
 633                }),
 634                SettingsPageItem::SectionHeader("Search"),
 635                SettingsPageItem::SettingItem(SettingItem {
 636                    title: "Search Wrap",
 637                    description: "Whether the editor search results will loop",
 638                    field: Box::new(SettingField {
 639                        pick: |settings_content| &settings_content.editor.search_wrap,
 640                        pick_mut: |settings_content| &mut settings_content.editor.search_wrap,
 641                    }),
 642                    metadata: None,
 643                }),
 644                SettingsPageItem::SettingItem(SettingItem {
 645                    title: "Seed Search Query From Cursor",
 646                    description: "When to populate a new search's query based on the text under the cursor",
 647                    field: Box::new(SettingField {
 648                        pick: |settings_content| {
 649                            &settings_content.editor.seed_search_query_from_cursor
 650                        },
 651                        pick_mut: |settings_content| {
 652                            &mut settings_content.editor.seed_search_query_from_cursor
 653                        },
 654                    }),
 655                    metadata: None,
 656                }),
 657                SettingsPageItem::SettingItem(SettingItem {
 658                    title: "Use Smartcase Search",
 659                    description: "Whether to use smartcase search",
 660                    field: Box::new(SettingField {
 661                        pick: |settings_content| &settings_content.editor.use_smartcase_search,
 662                        pick_mut: |settings_content| {
 663                            &mut settings_content.editor.use_smartcase_search
 664                        },
 665                    }),
 666                    metadata: None,
 667                }),
 668                SettingsPageItem::SectionHeader("Editor Behavior"),
 669                SettingsPageItem::SettingItem(SettingItem {
 670                    title: "Redact Private Values",
 671                    description: "Hide the values of variables in private files",
 672                    field: Box::new(SettingField {
 673                        pick: |settings_content| &settings_content.editor.redact_private_values,
 674                        pick_mut: |settings_content| {
 675                            &mut settings_content.editor.redact_private_values
 676                        },
 677                    }),
 678                    metadata: None,
 679                }),
 680                SettingsPageItem::SettingItem(SettingItem {
 681                    title: "Middle Click Paste",
 682                    description: "Whether to enable middle-click paste on Linux",
 683                    field: Box::new(SettingField {
 684                        pick: |settings_content| &settings_content.editor.middle_click_paste,
 685                        pick_mut: |settings_content| {
 686                            &mut settings_content.editor.middle_click_paste
 687                        },
 688                    }),
 689                    metadata: None,
 690                }),
 691                SettingsPageItem::SettingItem(SettingItem {
 692                    title: "Double Click In Multibuffer",
 693                    description: "What to do when multibuffer is double clicked in some of its excerpts",
 694                    field: Box::new(SettingField {
 695                        pick: |settings_content| {
 696                            &settings_content.editor.double_click_in_multibuffer
 697                        },
 698                        pick_mut: |settings_content| {
 699                            &mut settings_content.editor.double_click_in_multibuffer
 700                        },
 701                    }),
 702                    metadata: None,
 703                }),
 704                SettingsPageItem::SettingItem(SettingItem {
 705                    title: "Go To Definition Fallback",
 706                    description: "Whether to follow-up empty go to definition responses from the language server",
 707                    field: Box::new(SettingField {
 708                        pick: |settings_content| &settings_content.editor.go_to_definition_fallback,
 709                        pick_mut: |settings_content| {
 710                            &mut settings_content.editor.go_to_definition_fallback
 711                        },
 712                    }),
 713                    metadata: None,
 714                }),
 715                SettingsPageItem::SectionHeader("Scrolling"),
 716                SettingsPageItem::SettingItem(SettingItem {
 717                    title: "Scroll Beyond Last Line",
 718                    description: "Whether the editor will scroll beyond the last line",
 719                    field: Box::new(SettingField {
 720                        pick: |settings_content| &settings_content.editor.scroll_beyond_last_line,
 721                        pick_mut: |settings_content| {
 722                            &mut settings_content.editor.scroll_beyond_last_line
 723                        },
 724                    }),
 725                    metadata: None,
 726                }),
 727                SettingsPageItem::SettingItem(SettingItem {
 728                    title: "Vertical Scroll Margin",
 729                    description: "The number of lines to keep above/below the cursor when auto-scrolling",
 730                    field: Box::new(SettingField {
 731                        pick: |settings_content| &settings_content.editor.vertical_scroll_margin,
 732                        pick_mut: |settings_content| {
 733                            &mut settings_content.editor.vertical_scroll_margin
 734                        },
 735                    }),
 736                    metadata: None,
 737                }),
 738                SettingsPageItem::SettingItem(SettingItem {
 739                    title: "Horizontal Scroll Margin",
 740                    description: "The number of characters to keep on either side when scrolling with the mouse",
 741                    field: Box::new(SettingField {
 742                        pick: |settings_content| &settings_content.editor.horizontal_scroll_margin,
 743                        pick_mut: |settings_content| {
 744                            &mut settings_content.editor.horizontal_scroll_margin
 745                        },
 746                    }),
 747                    metadata: None,
 748                }),
 749                SettingsPageItem::SettingItem(SettingItem {
 750                    title: "Scroll Sensitivity",
 751                    description: "Scroll sensitivity multiplier for both horizontal and vertical scrolling",
 752                    field: Box::new(SettingField {
 753                        pick: |settings_content| &settings_content.editor.scroll_sensitivity,
 754                        pick_mut: |settings_content| {
 755                            &mut settings_content.editor.scroll_sensitivity
 756                        },
 757                    }),
 758                    metadata: None,
 759                }),
 760                SettingsPageItem::SettingItem(SettingItem {
 761                    title: "Fast Scroll Sensitivity",
 762                    description: "Fast Scroll sensitivity multiplier for both horizontal and vertical scrolling",
 763                    field: Box::new(SettingField {
 764                        pick: |settings_content| &settings_content.editor.fast_scroll_sensitivity,
 765                        pick_mut: |settings_content| {
 766                            &mut settings_content.editor.fast_scroll_sensitivity
 767                        },
 768                    }),
 769                    metadata: None,
 770                }),
 771                SettingsPageItem::SettingItem(SettingItem {
 772                    title: "Autoscroll On Clicks",
 773                    description: "Whether to scroll when clicking near the edge of the visible text area",
 774                    field: Box::new(SettingField {
 775                        pick: |settings_content| &settings_content.editor.autoscroll_on_clicks,
 776                        pick_mut: |settings_content| {
 777                            &mut settings_content.editor.autoscroll_on_clicks
 778                        },
 779                    }),
 780                    metadata: None,
 781                }),
 782                SettingsPageItem::SectionHeader("Auto Actions"),
 783                SettingsPageItem::SettingItem(SettingItem {
 784                    title: "Use Autoclose",
 785                    description: "Whether to automatically type closing characters for you",
 786                    field: Box::new(SettingField {
 787                        pick: |settings_content| {
 788                            &settings_content
 789                                .project
 790                                .all_languages
 791                                .defaults
 792                                .use_autoclose
 793                        },
 794                        pick_mut: |settings_content| {
 795                            &mut settings_content
 796                                .project
 797                                .all_languages
 798                                .defaults
 799                                .use_autoclose
 800                        },
 801                    }),
 802                    metadata: None,
 803                }),
 804                SettingsPageItem::SettingItem(SettingItem {
 805                    title: "Use Auto Surround",
 806                    description: "Whether to automatically surround text with characters for you",
 807                    field: Box::new(SettingField {
 808                        pick: |settings_content| {
 809                            &settings_content
 810                                .project
 811                                .all_languages
 812                                .defaults
 813                                .use_auto_surround
 814                        },
 815                        pick_mut: |settings_content| {
 816                            &mut settings_content
 817                                .project
 818                                .all_languages
 819                                .defaults
 820                                .use_auto_surround
 821                        },
 822                    }),
 823                    metadata: None,
 824                }),
 825                SettingsPageItem::SettingItem(SettingItem {
 826                    title: "Use On Type Format",
 827                    description: "Whether to use additional LSP queries to format the code after every trigger symbol input",
 828                    field: Box::new(SettingField {
 829                        pick: |settings_content| {
 830                            &settings_content
 831                                .project
 832                                .all_languages
 833                                .defaults
 834                                .use_on_type_format
 835                        },
 836                        pick_mut: |settings_content| {
 837                            &mut settings_content
 838                                .project
 839                                .all_languages
 840                                .defaults
 841                                .use_on_type_format
 842                        },
 843                    }),
 844                    metadata: None,
 845                }),
 846                SettingsPageItem::SettingItem(SettingItem {
 847                    title: "Always Treat Brackets As Autoclosed",
 848                    description: "Controls how the editor handles the autoclosed characters",
 849                    field: Box::new(SettingField {
 850                        pick: |settings_content| {
 851                            &settings_content
 852                                .project
 853                                .all_languages
 854                                .defaults
 855                                .always_treat_brackets_as_autoclosed
 856                        },
 857                        pick_mut: |settings_content| {
 858                            &mut settings_content
 859                                .project
 860                                .all_languages
 861                                .defaults
 862                                .always_treat_brackets_as_autoclosed
 863                        },
 864                    }),
 865                    metadata: None,
 866                }),
 867                SettingsPageItem::SectionHeader("Formatting"),
 868                SettingsPageItem::SettingItem(SettingItem {
 869                    title: "Remove Trailing Whitespace On Save",
 870                    description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
 871                    field: Box::new(SettingField {
 872                        pick: |settings_content| {
 873                            &settings_content
 874                                .project
 875                                .all_languages
 876                                .defaults
 877                                .remove_trailing_whitespace_on_save
 878                        },
 879                        pick_mut: |settings_content| {
 880                            &mut settings_content
 881                                .project
 882                                .all_languages
 883                                .defaults
 884                                .remove_trailing_whitespace_on_save
 885                        },
 886                    }),
 887                    metadata: None,
 888                }),
 889                SettingsPageItem::SettingItem(SettingItem {
 890                    title: "Ensure Final Newline On Save",
 891                    description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
 892                    field: Box::new(SettingField {
 893                        pick: |settings_content| {
 894                            &settings_content
 895                                .project
 896                                .all_languages
 897                                .defaults
 898                                .ensure_final_newline_on_save
 899                        },
 900                        pick_mut: |settings_content| {
 901                            &mut settings_content
 902                                .project
 903                                .all_languages
 904                                .defaults
 905                                .ensure_final_newline_on_save
 906                        },
 907                    }),
 908                    metadata: None,
 909                }),
 910                SettingsPageItem::SettingItem(SettingItem {
 911                    title: "Extend Comment On Newline",
 912                    description: "Whether to start a new line with a comment when a previous line is a comment as well",
 913                    field: Box::new(SettingField {
 914                        pick: |settings_content| {
 915                            &settings_content
 916                                .project
 917                                .all_languages
 918                                .defaults
 919                                .extend_comment_on_newline
 920                        },
 921                        pick_mut: |settings_content| {
 922                            &mut settings_content
 923                                .project
 924                                .all_languages
 925                                .defaults
 926                                .extend_comment_on_newline
 927                        },
 928                    }),
 929                    metadata: None,
 930                }),
 931                SettingsPageItem::SectionHeader("Completions"),
 932                SettingsPageItem::SettingItem(SettingItem {
 933                    title: "Show Completions On Input",
 934                    description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
 935                    field: Box::new(SettingField {
 936                        pick: |settings_content| {
 937                            &settings_content
 938                                .project
 939                                .all_languages
 940                                .defaults
 941                                .show_completions_on_input
 942                        },
 943                        pick_mut: |settings_content| {
 944                            &mut settings_content
 945                                .project
 946                                .all_languages
 947                                .defaults
 948                                .show_completions_on_input
 949                        },
 950                    }),
 951                    metadata: None,
 952                }),
 953                SettingsPageItem::SettingItem(SettingItem {
 954                    title: "Show Completion Documentation",
 955                    description: "Whether to display inline and alongside documentation for items in the completions menu",
 956                    field: Box::new(SettingField {
 957                        pick: |settings_content| {
 958                            &settings_content
 959                                .project
 960                                .all_languages
 961                                .defaults
 962                                .show_completion_documentation
 963                        },
 964                        pick_mut: |settings_content| {
 965                            &mut settings_content
 966                                .project
 967                                .all_languages
 968                                .defaults
 969                                .show_completion_documentation
 970                        },
 971                    }),
 972                    metadata: None,
 973                }),
 974                SettingsPageItem::SettingItem(SettingItem {
 975                    title: "Auto Signature Help",
 976                    description: "Whether to automatically show a signature help pop-up or not",
 977                    field: Box::new(SettingField {
 978                        pick: |settings_content| &settings_content.editor.auto_signature_help,
 979                        pick_mut: |settings_content| {
 980                            &mut settings_content.editor.auto_signature_help
 981                        },
 982                    }),
 983                    metadata: None,
 984                }),
 985                SettingsPageItem::SettingItem(SettingItem {
 986                    title: "Show Signature Help After Edits",
 987                    description: "Whether to show the signature help pop-up after completions or bracket pairs inserted",
 988                    field: Box::new(SettingField {
 989                        pick: |settings_content| {
 990                            &settings_content.editor.show_signature_help_after_edits
 991                        },
 992                        pick_mut: |settings_content| {
 993                            &mut settings_content.editor.show_signature_help_after_edits
 994                        },
 995                    }),
 996                    metadata: None,
 997                }),
 998                SettingsPageItem::SettingItem(SettingItem {
 999                    title: "Snippet Sort Order",
1000                    description: "Determines how snippets are sorted relative to other completion items",
1001                    field: Box::new(SettingField {
1002                        pick: |settings_content| &settings_content.editor.snippet_sort_order,
1003                        pick_mut: |settings_content| {
1004                            &mut settings_content.editor.snippet_sort_order
1005                        },
1006                    }),
1007                    metadata: None,
1008                }),
1009                SettingsPageItem::SectionHeader("Hover"),
1010                SettingsPageItem::SettingItem(SettingItem {
1011                    title: "Hover Popover Enabled",
1012                    description: "Whether to show the informational hover box when moving the mouse over symbols in the editor",
1013                    field: Box::new(SettingField {
1014                        pick: |settings_content| &settings_content.editor.hover_popover_enabled,
1015                        pick_mut: |settings_content| {
1016                            &mut settings_content.editor.hover_popover_enabled
1017                        },
1018                    }),
1019                    metadata: None,
1020                }),
1021                // todo(settings ui): add units to this numeric stepper
1022                SettingsPageItem::SettingItem(SettingItem {
1023                    title: "Hover Popover Delay",
1024                    description: "Time to wait in milliseconds before showing the informational hover box",
1025                    field: Box::new(SettingField {
1026                        pick: |settings_content| &settings_content.editor.hover_popover_delay,
1027                        pick_mut: |settings_content| {
1028                            &mut settings_content.editor.hover_popover_delay
1029                        },
1030                    }),
1031                    metadata: None,
1032                }),
1033                SettingsPageItem::SectionHeader("Code Actions"),
1034                SettingsPageItem::SettingItem(SettingItem {
1035                    title: "Inline Code Actions",
1036                    description: "Whether to show code action button at start of buffer line",
1037                    field: Box::new(SettingField {
1038                        pick: |settings_content| &settings_content.editor.inline_code_actions,
1039                        pick_mut: |settings_content| {
1040                            &mut settings_content.editor.inline_code_actions
1041                        },
1042                    }),
1043                    metadata: None,
1044                }),
1045                SettingsPageItem::SectionHeader("Selection"),
1046                SettingsPageItem::SettingItem(SettingItem {
1047                    title: "Drag And Drop Selection",
1048                    description: "Whether to enable drag and drop selection",
1049                    field: Box::new(SettingField {
1050                        pick: |settings_content| {
1051                            if let Some(drag_and_drop) =
1052                                &settings_content.editor.drag_and_drop_selection
1053                            {
1054                                &drag_and_drop.enabled
1055                            } else {
1056                                &None
1057                            }
1058                        },
1059                        pick_mut: |settings_content| {
1060                            &mut settings_content
1061                                .editor
1062                                .drag_and_drop_selection
1063                                .get_or_insert_default()
1064                                .enabled
1065                        },
1066                    }),
1067                    metadata: None,
1068                }),
1069                // todo(settings_ui): Needs numeric stepper
1070                // SettingsPageItem::SettingItem(SettingItem {
1071                //     title: "Drag And Drop Selection Delay",
1072                //     description: "Delay in milliseconds before drag and drop selection starts",
1073                //     field: Box::new(SettingField {
1074                //         pick: |settings_content| {
1075                //             if let Some(drag_and_drop) = &settings_content.editor.drag_and_drop_selection {
1076                //                 &drag_and_drop.delay
1077                //             } else {
1078                //                 &None
1079                //             }
1080                //         },
1081                //         pick_mut: |settings_content| {
1082                //             &mut settings_content.editor.drag_and_drop_selection.get_or_insert_default().delay
1083                //         },
1084                //     }),
1085                //     metadata: None,
1086                // }),
1087                SettingsPageItem::SectionHeader("Line Numbers"),
1088                SettingsPageItem::SettingItem(SettingItem {
1089                    title: "Relative Line Numbers",
1090                    description: "Whether the line numbers on editors gutter are relative or not",
1091                    field: Box::new(SettingField {
1092                        pick: |settings_content| &settings_content.editor.relative_line_numbers,
1093                        pick_mut: |settings_content| {
1094                            &mut settings_content.editor.relative_line_numbers
1095                        },
1096                    }),
1097                    metadata: None,
1098                }),
1099                SettingsPageItem::SectionHeader("Gutter"),
1100                SettingsPageItem::SettingItem(SettingItem {
1101                    title: "Show Line Numbers",
1102                    description: "Whether to show line numbers in the gutter",
1103                    field: Box::new(SettingField {
1104                        pick: |settings_content| {
1105                            if let Some(gutter) = &settings_content.editor.gutter {
1106                                &gutter.line_numbers
1107                            } else {
1108                                &None
1109                            }
1110                        },
1111                        pick_mut: |settings_content| {
1112                            &mut settings_content
1113                                .editor
1114                                .gutter
1115                                .get_or_insert_default()
1116                                .line_numbers
1117                        },
1118                    }),
1119                    metadata: None,
1120                }),
1121                SettingsPageItem::SettingItem(SettingItem {
1122                    title: "Show Runnables",
1123                    description: "Whether to show runnable buttons in the gutter",
1124                    field: Box::new(SettingField {
1125                        pick: |settings_content| {
1126                            if let Some(gutter) = &settings_content.editor.gutter {
1127                                &gutter.runnables
1128                            } else {
1129                                &None
1130                            }
1131                        },
1132                        pick_mut: |settings_content| {
1133                            &mut settings_content
1134                                .editor
1135                                .gutter
1136                                .get_or_insert_default()
1137                                .runnables
1138                        },
1139                    }),
1140                    metadata: None,
1141                }),
1142                SettingsPageItem::SettingItem(SettingItem {
1143                    title: "Show Breakpoints",
1144                    description: "Whether to show breakpoints in the gutter",
1145                    field: Box::new(SettingField {
1146                        pick: |settings_content| {
1147                            if let Some(gutter) = &settings_content.editor.gutter {
1148                                &gutter.breakpoints
1149                            } else {
1150                                &None
1151                            }
1152                        },
1153                        pick_mut: |settings_content| {
1154                            &mut settings_content
1155                                .editor
1156                                .gutter
1157                                .get_or_insert_default()
1158                                .breakpoints
1159                        },
1160                    }),
1161                    metadata: None,
1162                }),
1163                SettingsPageItem::SettingItem(SettingItem {
1164                    title: "Show Folds",
1165                    description: "Whether to show code folding controls in the gutter",
1166                    field: Box::new(SettingField {
1167                        pick: |settings_content| {
1168                            if let Some(gutter) = &settings_content.editor.gutter {
1169                                &gutter.folds
1170                            } else {
1171                                &None
1172                            }
1173                        },
1174                        pick_mut: |settings_content| {
1175                            &mut settings_content.editor.gutter.get_or_insert_default().folds
1176                        },
1177                    }),
1178                    metadata: None,
1179                }),
1180                SettingsPageItem::SectionHeader("Tabs"),
1181                SettingsPageItem::SettingItem(SettingItem {
1182                    title: "Show Tab Bar",
1183                    description: "Whether or not to show the tab bar in the editor",
1184                    field: Box::new(SettingField {
1185                        pick: |settings_content| {
1186                            if let Some(tab_bar) = &settings_content.tab_bar {
1187                                &tab_bar.show
1188                            } else {
1189                                &None
1190                            }
1191                        },
1192                        pick_mut: |settings_content| {
1193                            &mut settings_content.tab_bar.get_or_insert_default().show
1194                        },
1195                    }),
1196                    metadata: None,
1197                }),
1198                SettingsPageItem::SettingItem(SettingItem {
1199                    title: "Show Git Status In Tabs",
1200                    description: "Whether to show the Git file status on a tab item",
1201                    field: Box::new(SettingField {
1202                        pick: |settings_content| {
1203                            if let Some(tabs) = &settings_content.tabs {
1204                                &tabs.git_status
1205                            } else {
1206                                &None
1207                            }
1208                        },
1209                        pick_mut: |settings_content| {
1210                            &mut settings_content.tabs.get_or_insert_default().git_status
1211                        },
1212                    }),
1213                    metadata: None,
1214                }),
1215                SettingsPageItem::SettingItem(SettingItem {
1216                    title: "Show File Icons In Tabs",
1217                    description: "Whether to show the file icon for a tab",
1218                    field: Box::new(SettingField {
1219                        pick: |settings_content| {
1220                            if let Some(tabs) = &settings_content.tabs {
1221                                &tabs.file_icons
1222                            } else {
1223                                &None
1224                            }
1225                        },
1226                        pick_mut: |settings_content| {
1227                            &mut settings_content.tabs.get_or_insert_default().file_icons
1228                        },
1229                    }),
1230                    metadata: None,
1231                }),
1232                SettingsPageItem::SettingItem(SettingItem {
1233                    title: "Tab Close Position",
1234                    description: "Position of the close button in a tab",
1235                    field: Box::new(SettingField {
1236                        pick: |settings_content| {
1237                            if let Some(tabs) = &settings_content.tabs {
1238                                &tabs.close_position
1239                            } else {
1240                                &None
1241                            }
1242                        },
1243                        pick_mut: |settings_content| {
1244                            &mut settings_content.tabs.get_or_insert_default().close_position
1245                        },
1246                    }),
1247                    metadata: None,
1248                }),
1249                // todo(settings_ui): Needs numeric stepper
1250                // SettingsPageItem::SettingItem(SettingItem {
1251                //     title: "Maximum Tabs",
1252                //     description: "Maximum open tabs in a pane. Will not close an unsaved tab",
1253                //     field: Box::new(SettingField {
1254                //         pick: |settings_content| &settings_content.workspace.max_tabs,
1255                //         pick_mut: |settings_content| &mut settings_content.workspace.max_tabs,
1256                //     }),
1257                //     metadata: None,
1258                // }),
1259            ],
1260        },
1261        SettingsPage {
1262            title: "Languages & Frameworks",
1263            items: {
1264                let mut items = vec![
1265                    SettingsPageItem::SectionHeader(LANGUAGES_SECTION_HEADER),
1266                    SettingsPageItem::SubPageLink(SubPageLink {
1267                        title: "JSON",
1268                        render: Arc::new(|this, window, cx| {
1269                            this.render_page_items(language_settings_data().iter(), window, cx)
1270                                .into_any_element()
1271                        }),
1272                    }),
1273                    SettingsPageItem::SubPageLink(SubPageLink {
1274                        title: "JSONC",
1275                        render: Arc::new(|this, window, cx| {
1276                            this.render_page_items(language_settings_data().iter(), window, cx)
1277                                .into_any_element()
1278                        }),
1279                    }),
1280                    SettingsPageItem::SubPageLink(SubPageLink {
1281                        title: "Rust",
1282                        render: Arc::new(|this, window, cx| {
1283                            this.render_page_items(language_settings_data().iter(), window, cx)
1284                                .into_any_element()
1285                        }),
1286                    }),
1287                    SettingsPageItem::SubPageLink(SubPageLink {
1288                        title: "Python",
1289                        render: Arc::new(|this, window, cx| {
1290                            this.render_page_items(language_settings_data().iter(), window, cx)
1291                                .into_any_element()
1292                        }),
1293                    }),
1294                    SettingsPageItem::SubPageLink(SubPageLink {
1295                        title: "TSX",
1296                        render: Arc::new(|this, window, cx| {
1297                            this.render_page_items(language_settings_data().iter(), window, cx)
1298                                .into_any_element()
1299                        }),
1300                    }),
1301                ];
1302
1303                items.push(SettingsPageItem::SectionHeader("Default Language Settings"));
1304                items.extend(language_settings_data());
1305
1306                items
1307            },
1308        },
1309        SettingsPage {
1310            title: "Workbench & Window",
1311            items: vec![
1312                SettingsPageItem::SectionHeader("Workbench"),
1313                SettingsPageItem::SettingItem(SettingItem {
1314                    title: "Editor Tabs",
1315                    description: "Whether or not to show the tab bar in the editor",
1316                    field: Box::new(SettingField {
1317                        pick: |settings_content| {
1318                            if let Some(tab_bar) = &settings_content.tab_bar {
1319                                &tab_bar.show
1320                            } else {
1321                                &None
1322                            }
1323                        },
1324                        pick_mut: |settings_content| {
1325                            &mut settings_content.tab_bar.get_or_insert_default().show
1326                        },
1327                    }),
1328                    metadata: None,
1329                }),
1330                SettingsPageItem::SettingItem(SettingItem {
1331                    title: "Active language Button",
1332                    description: "Whether to show the active language button in the status bar",
1333                    field: Box::new(SettingField {
1334                        pick: |settings_content| {
1335                            if let Some(status_bar) = &settings_content.status_bar {
1336                                &status_bar.active_language_button
1337                            } else {
1338                                &None
1339                            }
1340                        },
1341                        pick_mut: |settings_content| {
1342                            &mut settings_content
1343                                .status_bar
1344                                .get_or_insert_default()
1345                                .active_language_button
1346                        },
1347                    }),
1348                    metadata: None,
1349                }),
1350                SettingsPageItem::SettingItem(SettingItem {
1351                    title: "Cursor Position Button",
1352                    description: "Whether to show the cursor position button in the status bar",
1353                    field: Box::new(SettingField {
1354                        pick: |settings_content| {
1355                            if let Some(status_bar) = &settings_content.status_bar {
1356                                &status_bar.cursor_position_button
1357                            } else {
1358                                &None
1359                            }
1360                        },
1361                        pick_mut: |settings_content| {
1362                            &mut settings_content
1363                                .status_bar
1364                                .get_or_insert_default()
1365                                .cursor_position_button
1366                        },
1367                    }),
1368                    metadata: None,
1369                }),
1370                SettingsPageItem::SectionHeader("Terminal"),
1371                SettingsPageItem::SettingItem(SettingItem {
1372                    title: "Terminal Button",
1373                    description: "Whether to show the terminal button in the status bar",
1374                    field: Box::new(SettingField {
1375                        pick: |settings_content| {
1376                            if let Some(terminal) = &settings_content.terminal {
1377                                &terminal.button
1378                            } else {
1379                                &None
1380                            }
1381                        },
1382                        pick_mut: |settings_content| {
1383                            &mut settings_content.terminal.get_or_insert_default().button
1384                        },
1385                    }),
1386                    metadata: None,
1387                }),
1388                SettingsPageItem::SettingItem(SettingItem {
1389                    title: "Show Navigation History Buttons",
1390                    description: "Whether or not to show the navigation history buttons in the tab bar",
1391                    field: Box::new(SettingField {
1392                        pick: |settings_content| {
1393                            if let Some(tab_bar) = &settings_content.tab_bar {
1394                                &tab_bar.show_nav_history_buttons
1395                            } else {
1396                                &None
1397                            }
1398                        },
1399                        pick_mut: |settings_content| {
1400                            &mut settings_content
1401                                .tab_bar
1402                                .get_or_insert_default()
1403                                .show_nav_history_buttons
1404                        },
1405                    }),
1406                    metadata: None,
1407                }),
1408            ],
1409        },
1410        SettingsPage {
1411            title: "Panels & Tools",
1412            items: vec![
1413                SettingsPageItem::SectionHeader("Project Panel"),
1414                SettingsPageItem::SettingItem(SettingItem {
1415                    title: "Project Panel Button",
1416                    description: "Whether to show the project panel button in the status bar",
1417                    field: Box::new(SettingField {
1418                        pick: |settings_content| {
1419                            if let Some(project_panel) = &settings_content.project_panel {
1420                                &project_panel.button
1421                            } else {
1422                                &None
1423                            }
1424                        },
1425                        pick_mut: |settings_content| {
1426                            &mut settings_content
1427                                .project_panel
1428                                .get_or_insert_default()
1429                                .button
1430                        },
1431                    }),
1432                    metadata: None,
1433                }),
1434                SettingsPageItem::SettingItem(SettingItem {
1435                    title: "Project Panel Dock",
1436                    description: "Where to dock the project panel",
1437                    field: Box::new(SettingField {
1438                        pick: |settings_content| {
1439                            if let Some(project_panel) = &settings_content.project_panel {
1440                                &project_panel.dock
1441                            } else {
1442                                &None
1443                            }
1444                        },
1445                        pick_mut: |settings_content| {
1446                            &mut settings_content.project_panel.get_or_insert_default().dock
1447                        },
1448                    }),
1449                    metadata: None,
1450                }),
1451                // todo(settings_ui): Needs numeric stepper
1452                // SettingsPageItem::SettingItem(SettingItem {
1453                //     title: "Project Panel Default Width",
1454                //     description: "Default width of the project panel in pixels",
1455                //     field: Box::new(SettingField {
1456                //         pick: |settings_content| {
1457                //             if let Some(project_panel) = &settings_content.project_panel {
1458                //                 &project_panel.default_width
1459                //             } else {
1460                //                 &None
1461                //             }
1462                //         },
1463                //         pick_mut: |settings_content| {
1464                //             &mut settings_content
1465                //                 .project_panel
1466                //                 .get_or_insert_default()
1467                //                 .default_width
1468                //         },
1469                //     }),
1470                //     metadata: None,
1471                // }),
1472                SettingsPageItem::SectionHeader("Terminal"),
1473                SettingsPageItem::SettingItem(SettingItem {
1474                    title: "Terminal Dock",
1475                    description: "Where to dock the terminal panel",
1476                    field: Box::new(SettingField {
1477                        pick: |settings_content| {
1478                            if let Some(terminal) = &settings_content.terminal {
1479                                &terminal.dock
1480                            } else {
1481                                &None
1482                            }
1483                        },
1484                        pick_mut: |settings_content| {
1485                            &mut settings_content.terminal.get_or_insert_default().dock
1486                        },
1487                    }),
1488                    metadata: None,
1489                }),
1490                SettingsPageItem::SectionHeader("Tab Settings"),
1491                SettingsPageItem::SettingItem(SettingItem {
1492                    title: "Activate On Close",
1493                    description: "What to do after closing the current tab",
1494                    field: Box::new(SettingField {
1495                        pick: |settings_content| {
1496                            if let Some(tabs) = &settings_content.tabs {
1497                                &tabs.activate_on_close
1498                            } else {
1499                                &None
1500                            }
1501                        },
1502                        pick_mut: |settings_content| {
1503                            &mut settings_content
1504                                .tabs
1505                                .get_or_insert_default()
1506                                .activate_on_close
1507                        },
1508                    }),
1509                    metadata: None,
1510                }),
1511                SettingsPageItem::SettingItem(SettingItem {
1512                    title: "Tab Show Diagnostics",
1513                    description: "Which files containing diagnostic errors/warnings to mark in the tabs",
1514                    field: Box::new(SettingField {
1515                        pick: |settings_content| {
1516                            if let Some(tabs) = &settings_content.tabs {
1517                                &tabs.show_diagnostics
1518                            } else {
1519                                &None
1520                            }
1521                        },
1522                        pick_mut: |settings_content| {
1523                            &mut settings_content
1524                                .tabs
1525                                .get_or_insert_default()
1526                                .show_diagnostics
1527                        },
1528                    }),
1529                    metadata: None,
1530                }),
1531                SettingsPageItem::SettingItem(SettingItem {
1532                    title: "Show Close Button",
1533                    description: "Controls the appearance behavior of the tab's close button",
1534                    field: Box::new(SettingField {
1535                        pick: |settings_content| {
1536                            if let Some(tabs) = &settings_content.tabs {
1537                                &tabs.show_close_button
1538                            } else {
1539                                &None
1540                            }
1541                        },
1542                        pick_mut: |settings_content| {
1543                            &mut settings_content
1544                                .tabs
1545                                .get_or_insert_default()
1546                                .show_close_button
1547                        },
1548                    }),
1549                    metadata: None,
1550                }),
1551                SettingsPageItem::SectionHeader("Preview Tabs"),
1552                SettingsPageItem::SettingItem(SettingItem {
1553                    title: "Preview Tabs Enabled",
1554                    description: "Whether to show opened editors as preview tabs",
1555                    field: Box::new(SettingField {
1556                        pick: |settings_content| {
1557                            if let Some(preview_tabs) = &settings_content.preview_tabs {
1558                                &preview_tabs.enabled
1559                            } else {
1560                                &None
1561                            }
1562                        },
1563                        pick_mut: |settings_content| {
1564                            &mut settings_content
1565                                .preview_tabs
1566                                .get_or_insert_default()
1567                                .enabled
1568                        },
1569                    }),
1570                    metadata: None,
1571                }),
1572                SettingsPageItem::SettingItem(SettingItem {
1573                    title: "Enable Preview From File Finder",
1574                    description: "Whether to open tabs in preview mode when selected from the file finder",
1575                    field: Box::new(SettingField {
1576                        pick: |settings_content| {
1577                            if let Some(preview_tabs) = &settings_content.preview_tabs {
1578                                &preview_tabs.enable_preview_from_file_finder
1579                            } else {
1580                                &None
1581                            }
1582                        },
1583                        pick_mut: |settings_content| {
1584                            &mut settings_content
1585                                .preview_tabs
1586                                .get_or_insert_default()
1587                                .enable_preview_from_file_finder
1588                        },
1589                    }),
1590                    metadata: None,
1591                }),
1592                SettingsPageItem::SettingItem(SettingItem {
1593                    title: "Enable Preview From Code Navigation",
1594                    description: "Whether a preview tab gets replaced when code navigation is used to navigate away from the tab",
1595                    field: Box::new(SettingField {
1596                        pick: |settings_content| {
1597                            if let Some(preview_tabs) = &settings_content.preview_tabs {
1598                                &preview_tabs.enable_preview_from_code_navigation
1599                            } else {
1600                                &None
1601                            }
1602                        },
1603                        pick_mut: |settings_content| {
1604                            &mut settings_content
1605                                .preview_tabs
1606                                .get_or_insert_default()
1607                                .enable_preview_from_code_navigation
1608                        },
1609                    }),
1610                    metadata: None,
1611                }),
1612            ],
1613        },
1614        SettingsPage {
1615            title: "Version Control",
1616            items: vec![
1617                SettingsPageItem::SectionHeader("Git"),
1618                SettingsPageItem::SettingItem(SettingItem {
1619                    title: "Git Gutter",
1620                    description: "Control whether the git gutter is shown",
1621                    field: Box::new(SettingField {
1622                        pick: |settings_content| {
1623                            if let Some(git) = &settings_content.git {
1624                                &git.git_gutter
1625                            } else {
1626                                &None
1627                            }
1628                        },
1629                        pick_mut: |settings_content| {
1630                            &mut settings_content.git.get_or_insert_default().git_gutter
1631                        },
1632                    }),
1633                    metadata: None,
1634                }),
1635                // todo(settings_ui): Figure out the right default for this value in default.json
1636                // SettingsPageItem::SettingItem(SettingItem {
1637                //     title: "Gutter Debounce",
1638                //     description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter",
1639                //     field: Box::new(SettingField {
1640                //         pick: |settings_content| {
1641                //             if let Some(git) = &settings_content.git {
1642                //                 &git.gutter_debounce
1643                //             } else {
1644                //                 &None
1645                //             }
1646                //         },
1647                //         pick_mut: |settings_content| {
1648                //             &mut settings_content.git.get_or_insert_default().gutter_debounce
1649                //         },
1650                //     }),
1651                //     metadata: None,
1652                // }),
1653                SettingsPageItem::SettingItem(SettingItem {
1654                    title: "Inline Blame Enabled",
1655                    description: "Whether or not to show git blame data inline in the currently focused line",
1656                    field: Box::new(SettingField {
1657                        pick: |settings_content| {
1658                            if let Some(git) = &settings_content.git {
1659                                if let Some(inline_blame) = &git.inline_blame {
1660                                    &inline_blame.enabled
1661                                } else {
1662                                    &None
1663                                }
1664                            } else {
1665                                &None
1666                            }
1667                        },
1668                        pick_mut: |settings_content| {
1669                            &mut settings_content
1670                                .git
1671                                .get_or_insert_default()
1672                                .inline_blame
1673                                .get_or_insert_default()
1674                                .enabled
1675                        },
1676                    }),
1677                    metadata: None,
1678                }),
1679                SettingsPageItem::SettingItem(SettingItem {
1680                    title: "Inline Blame Delay",
1681                    description: "The delay after which the inline blame information is shown",
1682                    field: Box::new(SettingField {
1683                        pick: |settings_content| {
1684                            if let Some(git) = &settings_content.git {
1685                                if let Some(inline_blame) = &git.inline_blame {
1686                                    &inline_blame.delay_ms
1687                                } else {
1688                                    &None
1689                                }
1690                            } else {
1691                                &None
1692                            }
1693                        },
1694                        pick_mut: |settings_content| {
1695                            &mut settings_content
1696                                .git
1697                                .get_or_insert_default()
1698                                .inline_blame
1699                                .get_or_insert_default()
1700                                .delay_ms
1701                        },
1702                    }),
1703                    metadata: None,
1704                }),
1705                SettingsPageItem::SettingItem(SettingItem {
1706                    title: "Inline Blame Padding",
1707                    description: "Padding between the end of the source line and the start of the inline blame in columns",
1708                    field: Box::new(SettingField {
1709                        pick: |settings_content| {
1710                            if let Some(git) = &settings_content.git {
1711                                if let Some(inline_blame) = &git.inline_blame {
1712                                    &inline_blame.padding
1713                                } else {
1714                                    &None
1715                                }
1716                            } else {
1717                                &None
1718                            }
1719                        },
1720                        pick_mut: |settings_content| {
1721                            &mut settings_content
1722                                .git
1723                                .get_or_insert_default()
1724                                .inline_blame
1725                                .get_or_insert_default()
1726                                .padding
1727                        },
1728                    }),
1729                    metadata: None,
1730                }),
1731                SettingsPageItem::SettingItem(SettingItem {
1732                    title: "Inline Blame Min Column",
1733                    description: "The minimum column number to show the inline blame information at",
1734                    field: Box::new(SettingField {
1735                        pick: |settings_content| {
1736                            if let Some(git) = &settings_content.git {
1737                                if let Some(inline_blame) = &git.inline_blame {
1738                                    &inline_blame.min_column
1739                                } else {
1740                                    &None
1741                                }
1742                            } else {
1743                                &None
1744                            }
1745                        },
1746                        pick_mut: |settings_content| {
1747                            &mut settings_content
1748                                .git
1749                                .get_or_insert_default()
1750                                .inline_blame
1751                                .get_or_insert_default()
1752                                .min_column
1753                        },
1754                    }),
1755                    metadata: None,
1756                }),
1757                SettingsPageItem::SettingItem(SettingItem {
1758                    title: "Show Commit Summary",
1759                    description: "Whether to show commit summary as part of the inline blame",
1760                    field: Box::new(SettingField {
1761                        pick: |settings_content| {
1762                            if let Some(git) = &settings_content.git {
1763                                if let Some(inline_blame) = &git.inline_blame {
1764                                    &inline_blame.show_commit_summary
1765                                } else {
1766                                    &None
1767                                }
1768                            } else {
1769                                &None
1770                            }
1771                        },
1772                        pick_mut: |settings_content| {
1773                            &mut settings_content
1774                                .git
1775                                .get_or_insert_default()
1776                                .inline_blame
1777                                .get_or_insert_default()
1778                                .show_commit_summary
1779                        },
1780                    }),
1781                    metadata: None,
1782                }),
1783                SettingsPageItem::SettingItem(SettingItem {
1784                    title: "Show Avatar",
1785                    description: "Whether to show the avatar of the author of the commit",
1786                    field: Box::new(SettingField {
1787                        pick: |settings_content| {
1788                            if let Some(git) = &settings_content.git {
1789                                if let Some(blame) = &git.blame {
1790                                    &blame.show_avatar
1791                                } else {
1792                                    &None
1793                                }
1794                            } else {
1795                                &None
1796                            }
1797                        },
1798                        pick_mut: |settings_content| {
1799                            &mut settings_content
1800                                .git
1801                                .get_or_insert_default()
1802                                .blame
1803                                .get_or_insert_default()
1804                                .show_avatar
1805                        },
1806                    }),
1807                    metadata: None,
1808                }),
1809                SettingsPageItem::SettingItem(SettingItem {
1810                    title: "Show Author Name In Branch Picker",
1811                    description: "Whether to show author name as part of the commit information in branch picker",
1812                    field: Box::new(SettingField {
1813                        pick: |settings_content| {
1814                            if let Some(git) = &settings_content.git {
1815                                if let Some(branch_picker) = &git.branch_picker {
1816                                    &branch_picker.show_author_name
1817                                } else {
1818                                    &None
1819                                }
1820                            } else {
1821                                &None
1822                            }
1823                        },
1824                        pick_mut: |settings_content| {
1825                            &mut settings_content
1826                                .git
1827                                .get_or_insert_default()
1828                                .branch_picker
1829                                .get_or_insert_default()
1830                                .show_author_name
1831                        },
1832                    }),
1833                    metadata: None,
1834                }),
1835                SettingsPageItem::SettingItem(SettingItem {
1836                    title: "Hunk Style",
1837                    description: "How git hunks are displayed visually in the editor",
1838                    field: Box::new(SettingField {
1839                        pick: |settings_content| {
1840                            if let Some(git) = &settings_content.git {
1841                                &git.hunk_style
1842                            } else {
1843                                &None
1844                            }
1845                        },
1846                        pick_mut: |settings_content| {
1847                            &mut settings_content.git.get_or_insert_default().hunk_style
1848                        },
1849                    }),
1850                    metadata: None,
1851                }),
1852            ],
1853        },
1854        SettingsPage {
1855            title: "System & Network",
1856            items: vec![
1857                SettingsPageItem::SectionHeader("Network"),
1858                // todo(settings_ui): Proxy needs a default
1859                // SettingsPageItem::SettingItem(SettingItem {
1860                //     title: "Proxy",
1861                //     description: "The proxy to use for network requests",
1862                //     field: Box::new(SettingField {
1863                //         pick: |settings_content| &settings_content.proxy,
1864                //         pick_mut: |settings_content| &mut settings_content.proxy,
1865                //     }),
1866                //     metadata: Some(Box::new(SettingsFieldMetadata {
1867                //         placeholder: Some("socks5h://localhost:10808"),
1868                //     })),
1869                // }),
1870                SettingsPageItem::SettingItem(SettingItem {
1871                    title: "Server URL",
1872                    description: "The URL of the Zed server to connect to",
1873                    field: Box::new(SettingField {
1874                        pick: |settings_content| &settings_content.server_url,
1875                        pick_mut: |settings_content| &mut settings_content.server_url,
1876                    }),
1877                    metadata: Some(Box::new(SettingsFieldMetadata {
1878                        placeholder: Some("https://zed.dev"),
1879                    })),
1880                }),
1881                SettingsPageItem::SectionHeader("System"),
1882                SettingsPageItem::SettingItem(SettingItem {
1883                    title: "Auto Update",
1884                    description: "Whether or not to automatically check for updates",
1885                    field: Box::new(SettingField {
1886                        pick: |settings_content| &settings_content.auto_update,
1887                        pick_mut: |settings_content| &mut settings_content.auto_update,
1888                    }),
1889                    metadata: None,
1890                }),
1891            ],
1892        },
1893        SettingsPage {
1894            title: "Diagnostics & Errors",
1895            items: vec![
1896                SettingsPageItem::SectionHeader("Display"),
1897                SettingsPageItem::SettingItem(SettingItem {
1898                    title: "Diagnostics Button",
1899                    description: "Whether to show the project diagnostics button in the status bar",
1900                    field: Box::new(SettingField {
1901                        pick: |settings_content| {
1902                            if let Some(diagnostics) = &settings_content.diagnostics {
1903                                &diagnostics.button
1904                            } else {
1905                                &None
1906                            }
1907                        },
1908                        pick_mut: |settings_content| {
1909                            &mut settings_content.diagnostics.get_or_insert_default().button
1910                        },
1911                    }),
1912                    metadata: None,
1913                }),
1914                SettingsPageItem::SectionHeader("Filtering"),
1915                SettingsPageItem::SettingItem(SettingItem {
1916                    title: "Max Severity",
1917                    description: "Which level to use to filter out diagnostics displayed in the editor",
1918                    field: Box::new(SettingField {
1919                        pick: |settings_content| &settings_content.editor.diagnostics_max_severity,
1920                        pick_mut: |settings_content| {
1921                            &mut settings_content.editor.diagnostics_max_severity
1922                        },
1923                    }),
1924                    metadata: None,
1925                }),
1926                SettingsPageItem::SettingItem(SettingItem {
1927                    title: "Include Warnings",
1928                    description: "Whether to show warnings or not by default",
1929                    field: Box::new(SettingField {
1930                        pick: |settings_content| {
1931                            if let Some(diagnostics) = &settings_content.diagnostics {
1932                                &diagnostics.include_warnings
1933                            } else {
1934                                &None
1935                            }
1936                        },
1937                        pick_mut: |settings_content| {
1938                            &mut settings_content
1939                                .diagnostics
1940                                .get_or_insert_default()
1941                                .include_warnings
1942                        },
1943                    }),
1944                    metadata: None,
1945                }),
1946                SettingsPageItem::SectionHeader("Inline"),
1947                SettingsPageItem::SettingItem(SettingItem {
1948                    title: "Inline Diagnostics Enabled",
1949                    description: "Whether to show diagnostics inline or not",
1950                    field: Box::new(SettingField {
1951                        pick: |settings_content| {
1952                            if let Some(diagnostics) = &settings_content.diagnostics {
1953                                if let Some(inline) = &diagnostics.inline {
1954                                    &inline.enabled
1955                                } else {
1956                                    &None
1957                                }
1958                            } else {
1959                                &None
1960                            }
1961                        },
1962                        pick_mut: |settings_content| {
1963                            &mut settings_content
1964                                .diagnostics
1965                                .get_or_insert_default()
1966                                .inline
1967                                .get_or_insert_default()
1968                                .enabled
1969                        },
1970                    }),
1971                    metadata: None,
1972                }),
1973                // todo(settings_ui): Needs numeric stepper
1974                SettingsPageItem::SettingItem(SettingItem {
1975                    title: "Inline Update Debounce",
1976                    description: "The delay in milliseconds to show inline diagnostics after the last diagnostic update",
1977                    field: Box::new(SettingField {
1978                        pick: |settings_content| {
1979                            if let Some(diagnostics) = &settings_content.diagnostics {
1980                                if let Some(inline) = &diagnostics.inline {
1981                                    &inline.update_debounce_ms
1982                                } else {
1983                                    &None
1984                                }
1985                            } else {
1986                                &None
1987                            }
1988                        },
1989                        pick_mut: |settings_content| {
1990                            &mut settings_content
1991                                .diagnostics
1992                                .get_or_insert_default()
1993                                .inline
1994                                .get_or_insert_default()
1995                                .update_debounce_ms
1996                        },
1997                    }),
1998                    metadata: None,
1999                }),
2000                // todo(settings_ui): Needs numeric stepper
2001                SettingsPageItem::SettingItem(SettingItem {
2002                    title: "Inline Padding",
2003                    description: "The amount of padding between the end of the source line and the start of the inline diagnostic",
2004                    field: Box::new(SettingField {
2005                        pick: |settings_content| {
2006                            if let Some(diagnostics) = &settings_content.diagnostics {
2007                                if let Some(inline) = &diagnostics.inline {
2008                                    &inline.padding
2009                                } else {
2010                                    &None
2011                                }
2012                            } else {
2013                                &None
2014                            }
2015                        },
2016                        pick_mut: |settings_content| {
2017                            &mut settings_content
2018                                .diagnostics
2019                                .get_or_insert_default()
2020                                .inline
2021                                .get_or_insert_default()
2022                                .padding
2023                        },
2024                    }),
2025                    metadata: None,
2026                }),
2027                // todo(settings_ui): Needs numeric stepper
2028                SettingsPageItem::SettingItem(SettingItem {
2029                    title: "Inline Min Column",
2030                    description: "The minimum column to display inline diagnostics",
2031                    field: Box::new(SettingField {
2032                        pick: |settings_content| {
2033                            if let Some(diagnostics) = &settings_content.diagnostics {
2034                                if let Some(inline) = &diagnostics.inline {
2035                                    &inline.min_column
2036                                } else {
2037                                    &None
2038                                }
2039                            } else {
2040                                &None
2041                            }
2042                        },
2043                        pick_mut: |settings_content| {
2044                            &mut settings_content
2045                                .diagnostics
2046                                .get_or_insert_default()
2047                                .inline
2048                                .get_or_insert_default()
2049                                .min_column
2050                        },
2051                    }),
2052                    metadata: None,
2053                }),
2054                SettingsPageItem::SectionHeader("Performance"),
2055                SettingsPageItem::SettingItem(SettingItem {
2056                    title: "LSP Pull Diagnostics Enabled",
2057                    description: "Whether to pull for diagnostics or not",
2058                    field: Box::new(SettingField {
2059                        pick: |settings_content| {
2060                            if let Some(diagnostics) = &settings_content.diagnostics {
2061                                if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
2062                                    &lsp_pull.enabled
2063                                } else {
2064                                    &None
2065                                }
2066                            } else {
2067                                &None
2068                            }
2069                        },
2070                        pick_mut: |settings_content| {
2071                            &mut settings_content
2072                                .diagnostics
2073                                .get_or_insert_default()
2074                                .lsp_pull_diagnostics
2075                                .get_or_insert_default()
2076                                .enabled
2077                        },
2078                    }),
2079                    metadata: None,
2080                }),
2081                // todo(settings_ui): Needs unit
2082                SettingsPageItem::SettingItem(SettingItem {
2083                    title: "LSP Pull Debounce",
2084                    description: "Minimum time to wait before pulling diagnostics from the language server(s)",
2085                    field: Box::new(SettingField {
2086                        pick: |settings_content| {
2087                            if let Some(diagnostics) = &settings_content.diagnostics {
2088                                if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
2089                                    &lsp_pull.debounce_ms
2090                                } else {
2091                                    &None
2092                                }
2093                            } else {
2094                                &None
2095                            }
2096                        },
2097                        pick_mut: |settings_content| {
2098                            &mut settings_content
2099                                .diagnostics
2100                                .get_or_insert_default()
2101                                .lsp_pull_diagnostics
2102                                .get_or_insert_default()
2103                                .debounce_ms
2104                        },
2105                    }),
2106                    metadata: None,
2107                }),
2108            ],
2109        },
2110        SettingsPage {
2111            title: "Collaboration",
2112            items: vec![
2113                SettingsPageItem::SectionHeader("Calls"),
2114                SettingsPageItem::SettingItem(SettingItem {
2115                    title: "Mute On Join",
2116                    description: "Whether the microphone should be muted when joining a channel or a call",
2117                    field: Box::new(SettingField {
2118                        pick: |settings_content| {
2119                            if let Some(calls) = &settings_content.calls {
2120                                &calls.mute_on_join
2121                            } else {
2122                                &None
2123                            }
2124                        },
2125                        pick_mut: |settings_content| {
2126                            &mut settings_content.calls.get_or_insert_default().mute_on_join
2127                        },
2128                    }),
2129                    metadata: None,
2130                }),
2131                SettingsPageItem::SettingItem(SettingItem {
2132                    title: "Share On Join",
2133                    description: "Whether your current project should be shared when joining an empty channel",
2134                    field: Box::new(SettingField {
2135                        pick: |settings_content| {
2136                            if let Some(calls) = &settings_content.calls {
2137                                &calls.share_on_join
2138                            } else {
2139                                &None
2140                            }
2141                        },
2142                        pick_mut: |settings_content| {
2143                            &mut settings_content.calls.get_or_insert_default().share_on_join
2144                        },
2145                    }),
2146                    metadata: None,
2147                }),
2148                SettingsPageItem::SectionHeader("Panel"),
2149                SettingsPageItem::SettingItem(SettingItem {
2150                    title: "Collaboration Panel Button",
2151                    description: "Whether to show the collaboration panel button in the status bar",
2152                    field: Box::new(SettingField {
2153                        pick: |settings_content| {
2154                            if let Some(collab) = &settings_content.collaboration_panel {
2155                                &collab.button
2156                            } else {
2157                                &None
2158                            }
2159                        },
2160                        pick_mut: |settings_content| {
2161                            &mut settings_content
2162                                .collaboration_panel
2163                                .get_or_insert_default()
2164                                .button
2165                        },
2166                    }),
2167                    metadata: None,
2168                }),
2169                SettingsPageItem::SectionHeader("Experimental"),
2170                SettingsPageItem::SettingItem(SettingItem {
2171                    title: "Rodio Audio",
2172                    description: "Opt into the new audio system",
2173                    field: Box::new(SettingField {
2174                        pick: |settings_content| {
2175                            if let Some(audio) = &settings_content.audio {
2176                                &audio.rodio_audio
2177                            } else {
2178                                &None
2179                            }
2180                        },
2181                        pick_mut: |settings_content| {
2182                            &mut settings_content.audio.get_or_insert_default().rodio_audio
2183                        },
2184                    }),
2185                    metadata: None,
2186                }),
2187            ],
2188        },
2189        SettingsPage {
2190            title: "AI",
2191            items: vec![
2192                SettingsPageItem::SectionHeader("General"),
2193                SettingsPageItem::SettingItem(SettingItem {
2194                    title: "Disable AI",
2195                    description: "Whether to disable all AI features in Zed",
2196                    field: Box::new(SettingField {
2197                        pick: |settings_content| &settings_content.disable_ai,
2198                        pick_mut: |settings_content| &mut settings_content.disable_ai,
2199                    }),
2200                    metadata: None,
2201                }),
2202            ],
2203        },
2204    ]
2205}
2206
2207pub(crate) fn project_settings_data() -> Vec<SettingsPage> {
2208    vec![
2209        SettingsPage {
2210            title: "Project",
2211            items: vec![
2212                SettingsPageItem::SectionHeader("Worktree Settings Content"),
2213                SettingsPageItem::SettingItem(SettingItem {
2214                    title: "Project Name",
2215                    description: "The displayed name of this project. If not set, the root directory name",
2216                    field: Box::new(SettingField {
2217                        pick: |settings_content| &settings_content.project.worktree.project_name,
2218                        pick_mut: |settings_content| {
2219                            &mut settings_content.project.worktree.project_name
2220                        },
2221                    }),
2222                    metadata: Some(Box::new(SettingsFieldMetadata {
2223                        placeholder: Some("A new name"),
2224                    })),
2225                }),
2226            ],
2227        },
2228        SettingsPage {
2229            title: "Appearance & Behavior",
2230            items: vec![
2231                SettingsPageItem::SectionHeader("Guides"),
2232                SettingsPageItem::SettingItem(SettingItem {
2233                    title: "Show Wrap Guides",
2234                    description: "Whether to show wrap guides (vertical rulers)",
2235                    field: Box::new(SettingField {
2236                        pick: |settings_content| {
2237                            &settings_content
2238                                .project
2239                                .all_languages
2240                                .defaults
2241                                .show_wrap_guides
2242                        },
2243                        pick_mut: |settings_content| {
2244                            &mut settings_content
2245                                .project
2246                                .all_languages
2247                                .defaults
2248                                .show_wrap_guides
2249                        },
2250                    }),
2251                    metadata: None,
2252                }),
2253                // todo(settings_ui): This needs a custom component
2254                // SettingsPageItem::SettingItem(SettingItem {
2255                //     title: "Wrap Guides",
2256                //     description: "Character counts at which to show wrap guides",
2257                //     field: Box::new(SettingField {
2258                //         pick: |settings_content| {
2259                //             &settings_content
2260                //                 .project
2261                //                 .all_languages
2262                //                 .defaults
2263                //                 .wrap_guides
2264                //         },
2265                //         pick_mut: |settings_content| {
2266                //             &mut settings_content
2267                //                 .project
2268                //                 .all_languages
2269                //                 .defaults
2270                //                 .wrap_guides
2271                //         },
2272                //     }),
2273                //     metadata: None,
2274                // }),
2275                SettingsPageItem::SectionHeader("Whitespace"),
2276                SettingsPageItem::SettingItem(SettingItem {
2277                    title: "Show Whitespace",
2278                    description: "Whether to show tabs and spaces",
2279                    field: Box::new(SettingField {
2280                        pick: |settings_content| {
2281                            &settings_content
2282                                .project
2283                                .all_languages
2284                                .defaults
2285                                .show_whitespaces
2286                        },
2287                        pick_mut: |settings_content| {
2288                            &mut settings_content
2289                                .project
2290                                .all_languages
2291                                .defaults
2292                                .show_whitespaces
2293                        },
2294                    }),
2295                    metadata: None,
2296                }),
2297            ],
2298        },
2299        SettingsPage {
2300            title: "Editing",
2301            items: vec![
2302                SettingsPageItem::SectionHeader("Indentation"),
2303                // todo(settings_ui): Needs numeric stepper
2304                // SettingsPageItem::SettingItem(SettingItem {
2305                //     title: "Tab Size",
2306                //     description: "How many columns a tab should occupy",
2307                //     field: Box::new(SettingField {
2308                //         pick: |settings_content| &settings_content.project.all_languages.defaults.tab_size,
2309                //         pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.tab_size,
2310                //     }),
2311                //     metadata: None,
2312                // }),
2313                SettingsPageItem::SettingItem(SettingItem {
2314                    title: "Hard Tabs",
2315                    description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
2316                    field: Box::new(SettingField {
2317                        pick: |settings_content| {
2318                            &settings_content.project.all_languages.defaults.hard_tabs
2319                        },
2320                        pick_mut: |settings_content| {
2321                            &mut settings_content.project.all_languages.defaults.hard_tabs
2322                        },
2323                    }),
2324                    metadata: None,
2325                }),
2326                SettingsPageItem::SettingItem(SettingItem {
2327                    title: "Auto Indent",
2328                    description: "Whether indentation should be adjusted based on the context whilst typing",
2329                    field: Box::new(SettingField {
2330                        pick: |settings_content| {
2331                            &settings_content.project.all_languages.defaults.auto_indent
2332                        },
2333                        pick_mut: |settings_content| {
2334                            &mut settings_content.project.all_languages.defaults.auto_indent
2335                        },
2336                    }),
2337                    metadata: None,
2338                }),
2339                SettingsPageItem::SettingItem(SettingItem {
2340                    title: "Auto Indent On Paste",
2341                    description: "Whether indentation of pasted content should be adjusted based on the context",
2342                    field: Box::new(SettingField {
2343                        pick: |settings_content| {
2344                            &settings_content
2345                                .project
2346                                .all_languages
2347                                .defaults
2348                                .auto_indent_on_paste
2349                        },
2350                        pick_mut: |settings_content| {
2351                            &mut settings_content
2352                                .project
2353                                .all_languages
2354                                .defaults
2355                                .auto_indent_on_paste
2356                        },
2357                    }),
2358                    metadata: None,
2359                }),
2360                SettingsPageItem::SectionHeader("Wrapping"),
2361                // todo(settings_ui): Needs numeric stepper
2362                // SettingsPageItem::SettingItem(SettingItem {
2363                //     title: "Preferred Line Length",
2364                //     description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
2365                //     field: Box::new(SettingField {
2366                //         pick: |settings_content| &settings_content.project.all_languages.defaults.preferred_line_length,
2367                //         pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.preferred_line_length,
2368                //     }),
2369                //     metadata: None,
2370                // }),
2371                SettingsPageItem::SettingItem(SettingItem {
2372                    title: "Soft Wrap",
2373                    description: "How to soft-wrap long lines of text",
2374                    field: Box::new(SettingField {
2375                        pick: |settings_content| {
2376                            &settings_content.project.all_languages.defaults.soft_wrap
2377                        },
2378                        pick_mut: |settings_content| {
2379                            &mut settings_content.project.all_languages.defaults.soft_wrap
2380                        },
2381                    }),
2382                    metadata: None,
2383                }),
2384                SettingsPageItem::SectionHeader("Auto Actions"),
2385                SettingsPageItem::SettingItem(SettingItem {
2386                    title: "Use Autoclose",
2387                    description: "Whether to automatically type closing characters for you",
2388                    field: Box::new(SettingField {
2389                        pick: |settings_content| {
2390                            &settings_content
2391                                .project
2392                                .all_languages
2393                                .defaults
2394                                .use_autoclose
2395                        },
2396                        pick_mut: |settings_content| {
2397                            &mut settings_content
2398                                .project
2399                                .all_languages
2400                                .defaults
2401                                .use_autoclose
2402                        },
2403                    }),
2404                    metadata: None,
2405                }),
2406                SettingsPageItem::SettingItem(SettingItem {
2407                    title: "Use Auto Surround",
2408                    description: "Whether to automatically surround text with characters for you",
2409                    field: Box::new(SettingField {
2410                        pick: |settings_content| {
2411                            &settings_content
2412                                .project
2413                                .all_languages
2414                                .defaults
2415                                .use_auto_surround
2416                        },
2417                        pick_mut: |settings_content| {
2418                            &mut settings_content
2419                                .project
2420                                .all_languages
2421                                .defaults
2422                                .use_auto_surround
2423                        },
2424                    }),
2425                    metadata: None,
2426                }),
2427                SettingsPageItem::SettingItem(SettingItem {
2428                    title: "Use On Type Format",
2429                    description: "Whether to use additional LSP queries to format the code after every trigger symbol input",
2430                    field: Box::new(SettingField {
2431                        pick: |settings_content| {
2432                            &settings_content
2433                                .project
2434                                .all_languages
2435                                .defaults
2436                                .use_on_type_format
2437                        },
2438                        pick_mut: |settings_content| {
2439                            &mut settings_content
2440                                .project
2441                                .all_languages
2442                                .defaults
2443                                .use_on_type_format
2444                        },
2445                    }),
2446                    metadata: None,
2447                }),
2448                SettingsPageItem::SettingItem(SettingItem {
2449                    title: "Always Treat Brackets As Autoclosed",
2450                    description: "Controls how the editor handles the autoclosed characters",
2451                    field: Box::new(SettingField {
2452                        pick: |settings_content| {
2453                            &settings_content
2454                                .project
2455                                .all_languages
2456                                .defaults
2457                                .always_treat_brackets_as_autoclosed
2458                        },
2459                        pick_mut: |settings_content| {
2460                            &mut settings_content
2461                                .project
2462                                .all_languages
2463                                .defaults
2464                                .always_treat_brackets_as_autoclosed
2465                        },
2466                    }),
2467                    metadata: None,
2468                }),
2469                SettingsPageItem::SectionHeader("Formatting"),
2470                SettingsPageItem::SettingItem(SettingItem {
2471                    title: "Remove Trailing Whitespace On Save",
2472                    description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
2473                    field: Box::new(SettingField {
2474                        pick: |settings_content| {
2475                            &settings_content
2476                                .project
2477                                .all_languages
2478                                .defaults
2479                                .remove_trailing_whitespace_on_save
2480                        },
2481                        pick_mut: |settings_content| {
2482                            &mut settings_content
2483                                .project
2484                                .all_languages
2485                                .defaults
2486                                .remove_trailing_whitespace_on_save
2487                        },
2488                    }),
2489                    metadata: None,
2490                }),
2491                SettingsPageItem::SettingItem(SettingItem {
2492                    title: "Ensure Final Newline On Save",
2493                    description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
2494                    field: Box::new(SettingField {
2495                        pick: |settings_content| {
2496                            &settings_content
2497                                .project
2498                                .all_languages
2499                                .defaults
2500                                .ensure_final_newline_on_save
2501                        },
2502                        pick_mut: |settings_content| {
2503                            &mut settings_content
2504                                .project
2505                                .all_languages
2506                                .defaults
2507                                .ensure_final_newline_on_save
2508                        },
2509                    }),
2510                    metadata: None,
2511                }),
2512                SettingsPageItem::SettingItem(SettingItem {
2513                    title: "Extend Comment On Newline",
2514                    description: "Whether to start a new line with a comment when a previous line is a comment as well",
2515                    field: Box::new(SettingField {
2516                        pick: |settings_content| {
2517                            &settings_content
2518                                .project
2519                                .all_languages
2520                                .defaults
2521                                .extend_comment_on_newline
2522                        },
2523                        pick_mut: |settings_content| {
2524                            &mut settings_content
2525                                .project
2526                                .all_languages
2527                                .defaults
2528                                .extend_comment_on_newline
2529                        },
2530                    }),
2531                    metadata: None,
2532                }),
2533                SettingsPageItem::SectionHeader("Completions"),
2534                SettingsPageItem::SettingItem(SettingItem {
2535                    title: "Show Completions On Input",
2536                    description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
2537                    field: Box::new(SettingField {
2538                        pick: |settings_content| {
2539                            &settings_content
2540                                .project
2541                                .all_languages
2542                                .defaults
2543                                .show_completions_on_input
2544                        },
2545                        pick_mut: |settings_content| {
2546                            &mut settings_content
2547                                .project
2548                                .all_languages
2549                                .defaults
2550                                .show_completions_on_input
2551                        },
2552                    }),
2553                    metadata: None,
2554                }),
2555                SettingsPageItem::SettingItem(SettingItem {
2556                    title: "Show Completion Documentation",
2557                    description: "Whether to display inline and alongside documentation for items in the completions menu",
2558                    field: Box::new(SettingField {
2559                        pick: |settings_content| {
2560                            &settings_content
2561                                .project
2562                                .all_languages
2563                                .defaults
2564                                .show_completion_documentation
2565                        },
2566                        pick_mut: |settings_content| {
2567                            &mut settings_content
2568                                .project
2569                                .all_languages
2570                                .defaults
2571                                .show_completion_documentation
2572                        },
2573                    }),
2574                    metadata: None,
2575                }),
2576            ],
2577        },
2578    ]
2579}
2580
2581const LANGUAGES_SECTION_HEADER: &'static str = "Languages";
2582
2583fn language_settings_data() -> Vec<SettingsPageItem> {
2584    fn current_language() -> Option<SharedString> {
2585        sub_page_stack().iter().find_map(|page| {
2586            (page.section_header == LANGUAGES_SECTION_HEADER)
2587                .then(|| SharedString::new_static(page.link.title))
2588        })
2589    }
2590
2591    fn language_settings_field<T>(
2592        settings_content: &SettingsContent,
2593        get: fn(&LanguageSettingsContent) -> &Option<T>,
2594    ) -> &Option<T> {
2595        let all_languages = &settings_content.project.all_languages;
2596        let mut language_content = None;
2597        if let Some(current_language) = current_language() {
2598            language_content = all_languages.languages.0.get(&current_language);
2599        }
2600        let value = language_content
2601            .map(get)
2602            .unwrap_or_else(|| get(&all_languages.defaults));
2603        return value;
2604    }
2605
2606    fn language_settings_field_mut<T>(
2607        settings_content: &mut SettingsContent,
2608        get: fn(&mut LanguageSettingsContent) -> &mut Option<T>,
2609    ) -> &mut Option<T> {
2610        let all_languages = &mut settings_content.project.all_languages;
2611        let language_content = if let Some(current_language) = current_language() {
2612            all_languages
2613                .languages
2614                .0
2615                .entry(current_language)
2616                .or_default()
2617        } else {
2618            &mut all_languages.defaults
2619        };
2620        return get(language_content);
2621    }
2622
2623    vec![
2624        SettingsPageItem::SectionHeader("Indentation"),
2625        SettingsPageItem::SettingItem(SettingItem {
2626            title: "Tab Size",
2627            description: "How many columns a tab should occupy",
2628            field: Box::new(SettingField {
2629                pick: |settings_content| {
2630                    language_settings_field(settings_content, |language| &language.tab_size)
2631                },
2632                pick_mut: |settings_content| {
2633                    language_settings_field_mut(settings_content, |language| &mut language.tab_size)
2634                },
2635            }),
2636            metadata: None,
2637        }),
2638        SettingsPageItem::SettingItem(SettingItem {
2639            title: "Hard Tabs",
2640            description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
2641            field: Box::new(SettingField {
2642                pick: |settings_content| {
2643                    language_settings_field(settings_content, |language| &language.hard_tabs)
2644                },
2645                pick_mut: |settings_content| {
2646                    language_settings_field_mut(settings_content, |language| {
2647                        &mut language.hard_tabs
2648                    })
2649                },
2650            }),
2651            metadata: None,
2652        }),
2653        SettingsPageItem::SettingItem(SettingItem {
2654            title: "Auto Indent",
2655            description: "Whether indentation should be adjusted based on the context whilst typing",
2656            field: Box::new(SettingField {
2657                pick: |settings_content| {
2658                    language_settings_field(settings_content, |language| &language.auto_indent)
2659                },
2660                pick_mut: |settings_content| {
2661                    language_settings_field_mut(settings_content, |language| {
2662                        &mut language.auto_indent
2663                    })
2664                },
2665            }),
2666            metadata: None,
2667        }),
2668        SettingsPageItem::SettingItem(SettingItem {
2669            title: "Auto Indent On Paste",
2670            description: "Whether indentation of pasted content should be adjusted based on the context",
2671            field: Box::new(SettingField {
2672                pick: |settings_content| {
2673                    language_settings_field(settings_content, |language| {
2674                        &language.auto_indent_on_paste
2675                    })
2676                },
2677                pick_mut: |settings_content| {
2678                    language_settings_field_mut(settings_content, |language| {
2679                        &mut language.auto_indent_on_paste
2680                    })
2681                },
2682            }),
2683            metadata: None,
2684        }),
2685        SettingsPageItem::SectionHeader("Wrapping"),
2686        SettingsPageItem::SettingItem(SettingItem {
2687            title: "Soft Wrap",
2688            description: "How to soft-wrap long lines of text",
2689            field: Box::new(SettingField {
2690                pick: |settings_content| {
2691                    language_settings_field(settings_content, |language| &language.soft_wrap)
2692                },
2693                pick_mut: |settings_content| {
2694                    language_settings_field_mut(settings_content, |language| {
2695                        &mut language.soft_wrap
2696                    })
2697                },
2698            }),
2699            metadata: None,
2700        }),
2701        SettingsPageItem::SettingItem(SettingItem {
2702            title: "Show Wrap Guides",
2703            description: "Whether to show wrap guides in the editor. Setting this to true will show a guide at the 'preferred_line_length' value if softwrap is set to 'preferred_line_length', and will show any additional guides as specified by the 'wrap_guides' setting",
2704            field: Box::new(SettingField {
2705                pick: |settings_content| {
2706                    language_settings_field(settings_content, |language| &language.show_wrap_guides)
2707                },
2708                pick_mut: |settings_content| {
2709                    language_settings_field_mut(settings_content, |language| {
2710                        &mut language.show_wrap_guides
2711                    })
2712                },
2713            }),
2714            metadata: None,
2715        }),
2716        SettingsPageItem::SettingItem(SettingItem {
2717            title: "Preferred Line Length",
2718            description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
2719            field: Box::new(SettingField {
2720                pick: |settings_content| {
2721                    language_settings_field(settings_content, |language| {
2722                        &language.preferred_line_length
2723                    })
2724                },
2725                pick_mut: |settings_content| {
2726                    language_settings_field_mut(settings_content, |language| {
2727                        &mut language.preferred_line_length
2728                    })
2729                },
2730            }),
2731            metadata: None,
2732        }),
2733        SettingsPageItem::SettingItem(SettingItem {
2734            title: "Wrap Guides",
2735            description: "Character counts at which to show wrap guides in the editor",
2736            field: Box::new(
2737                SettingField {
2738                    pick: |settings_content| {
2739                        language_settings_field(settings_content, |language| &language.wrap_guides)
2740                    },
2741                    pick_mut: |settings_content| {
2742                        language_settings_field_mut(settings_content, |language| {
2743                            &mut language.wrap_guides
2744                        })
2745                    },
2746                }
2747                .unimplemented(),
2748            ),
2749            metadata: None,
2750        }),
2751        SettingsPageItem::SettingItem(SettingItem {
2752            title: "Allow Rewrap",
2753            description: "Controls where the `editor::Rewrap` action is allowed for this language",
2754            field: Box::new(SettingField {
2755                pick: |settings_content| {
2756                    language_settings_field(settings_content, |language| &language.allow_rewrap)
2757                },
2758                pick_mut: |settings_content| {
2759                    language_settings_field_mut(settings_content, |language| {
2760                        &mut language.allow_rewrap
2761                    })
2762                },
2763            }),
2764            metadata: None,
2765        }),
2766        SettingsPageItem::SectionHeader("Indent Guides"),
2767        SettingsPageItem::SettingItem(SettingItem {
2768            title: "Enabled",
2769            description: "Whether to display indent guides in the editor",
2770            field: Box::new(SettingField {
2771                pick: |settings_content| {
2772                    language_settings_field(settings_content, |language| {
2773                        if let Some(indent_guides) = &language.indent_guides {
2774                            &indent_guides.enabled
2775                        } else {
2776                            &None
2777                        }
2778                    })
2779                },
2780                pick_mut: |settings_content| {
2781                    language_settings_field_mut(settings_content, |language| {
2782                        &mut language.indent_guides.get_or_insert_default().enabled
2783                    })
2784                },
2785            }),
2786            metadata: None,
2787        }),
2788        SettingsPageItem::SettingItem(SettingItem {
2789            title: "Line Width",
2790            description: "The width of the indent guides in pixels, between 1 and 10",
2791            field: Box::new(SettingField {
2792                pick: |settings_content| {
2793                    language_settings_field(settings_content, |language| {
2794                        if let Some(indent_guides) = &language.indent_guides {
2795                            &indent_guides.line_width
2796                        } else {
2797                            &None
2798                        }
2799                    })
2800                },
2801                pick_mut: |settings_content| {
2802                    language_settings_field_mut(settings_content, |language| {
2803                        &mut language.indent_guides.get_or_insert_default().line_width
2804                    })
2805                },
2806            }),
2807            metadata: None,
2808        }),
2809        SettingsPageItem::SettingItem(SettingItem {
2810            title: "Active Line Width",
2811            description: "The width of the active indent guide in pixels, between 1 and 10",
2812            field: Box::new(SettingField {
2813                pick: |settings_content| {
2814                    language_settings_field(settings_content, |language| {
2815                        if let Some(indent_guides) = &language.indent_guides {
2816                            &indent_guides.active_line_width
2817                        } else {
2818                            &None
2819                        }
2820                    })
2821                },
2822                pick_mut: |settings_content| {
2823                    language_settings_field_mut(settings_content, |language| {
2824                        &mut language
2825                            .indent_guides
2826                            .get_or_insert_default()
2827                            .active_line_width
2828                    })
2829                },
2830            }),
2831            metadata: None,
2832        }),
2833        SettingsPageItem::SettingItem(SettingItem {
2834            title: "Coloring",
2835            description: "Determines how indent guides are colored",
2836            field: Box::new(SettingField {
2837                pick: |settings_content| {
2838                    language_settings_field(settings_content, |language| {
2839                        if let Some(indent_guides) = &language.indent_guides {
2840                            &indent_guides.coloring
2841                        } else {
2842                            &None
2843                        }
2844                    })
2845                },
2846                pick_mut: |settings_content| {
2847                    language_settings_field_mut(settings_content, |language| {
2848                        &mut language.indent_guides.get_or_insert_default().coloring
2849                    })
2850                },
2851            }),
2852            metadata: None,
2853        }),
2854        SettingsPageItem::SettingItem(SettingItem {
2855            title: "Background Coloring",
2856            description: "Determines how indent guide backgrounds are colored",
2857            field: Box::new(SettingField {
2858                pick: |settings_content| {
2859                    language_settings_field(settings_content, |language| {
2860                        if let Some(indent_guides) = &language.indent_guides {
2861                            &indent_guides.background_coloring
2862                        } else {
2863                            &None
2864                        }
2865                    })
2866                },
2867                pick_mut: |settings_content| {
2868                    language_settings_field_mut(settings_content, |language| {
2869                        &mut language
2870                            .indent_guides
2871                            .get_or_insert_default()
2872                            .background_coloring
2873                    })
2874                },
2875            }),
2876            metadata: None,
2877        }),
2878        SettingsPageItem::SectionHeader("Formatting"),
2879        SettingsPageItem::SettingItem(SettingItem {
2880            title: "Format On Save",
2881            description: "Whether or not to perform a buffer format before saving",
2882            field: Box::new(
2883                // TODO(settings_ui): this setting should just be a bool
2884                SettingField {
2885                    pick: |settings_content| {
2886                        language_settings_field(settings_content, |language| {
2887                            &language.format_on_save
2888                        })
2889                    },
2890                    pick_mut: |settings_content| {
2891                        language_settings_field_mut(settings_content, |language| {
2892                            &mut language.format_on_save
2893                        })
2894                    },
2895                },
2896            ),
2897            metadata: None,
2898        }),
2899        SettingsPageItem::SettingItem(SettingItem {
2900            title: "Remove Trailing Whitespace On Save",
2901            description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
2902            field: Box::new(SettingField {
2903                pick: |settings_content| {
2904                    language_settings_field(settings_content, |language| {
2905                        &language.remove_trailing_whitespace_on_save
2906                    })
2907                },
2908                pick_mut: |settings_content| {
2909                    language_settings_field_mut(settings_content, |language| {
2910                        &mut language.remove_trailing_whitespace_on_save
2911                    })
2912                },
2913            }),
2914            metadata: None,
2915        }),
2916        SettingsPageItem::SettingItem(SettingItem {
2917            title: "Ensure Final Newline On Save",
2918            description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
2919            field: Box::new(SettingField {
2920                pick: |settings_content| {
2921                    language_settings_field(settings_content, |language| {
2922                        &language.ensure_final_newline_on_save
2923                    })
2924                },
2925                pick_mut: |settings_content| {
2926                    language_settings_field_mut(settings_content, |language| {
2927                        &mut language.ensure_final_newline_on_save
2928                    })
2929                },
2930            }),
2931            metadata: None,
2932        }),
2933        SettingsPageItem::SettingItem(SettingItem {
2934            title: "Formatter",
2935            description: "How to perform a buffer format",
2936            field: Box::new(
2937                SettingField {
2938                    pick: |settings_content| {
2939                        language_settings_field(settings_content, |language| &language.formatter)
2940                    },
2941                    pick_mut: |settings_content| {
2942                        language_settings_field_mut(settings_content, |language| {
2943                            &mut language.formatter
2944                        })
2945                    },
2946                }
2947                .unimplemented(),
2948            ),
2949            metadata: None,
2950        }),
2951        SettingsPageItem::SettingItem(SettingItem {
2952            title: "Use On Type Format",
2953            description: "Whether to use additional LSP queries to format (and amend) the code after every \"trigger\" symbol input, defined by LSP server capabilities",
2954            field: Box::new(SettingField {
2955                pick: |settings_content| {
2956                    language_settings_field(settings_content, |language| {
2957                        &language.use_on_type_format
2958                    })
2959                },
2960                pick_mut: |settings_content| {
2961                    language_settings_field_mut(settings_content, |language| {
2962                        &mut language.use_on_type_format
2963                    })
2964                },
2965            }),
2966            metadata: None,
2967        }),
2968        SettingsPageItem::SettingItem(SettingItem {
2969            title: "Code Actions On Format",
2970            description: "Which code actions to run on save after the formatter. These are not run if formatting is off",
2971            field: Box::new(
2972                SettingField {
2973                    pick: |settings_content| {
2974                        language_settings_field(settings_content, |language| {
2975                            &language.code_actions_on_format
2976                        })
2977                    },
2978                    pick_mut: |settings_content| {
2979                        language_settings_field_mut(settings_content, |language| {
2980                            &mut language.code_actions_on_format
2981                        })
2982                    },
2983                }
2984                .unimplemented(),
2985            ),
2986            metadata: None,
2987        }),
2988        SettingsPageItem::SectionHeader("Prettier"),
2989        SettingsPageItem::SettingItem(SettingItem {
2990            title: "Allowed",
2991            description: "Enables or disables formatting with Prettier for a given language",
2992            field: Box::new(SettingField {
2993                pick: |settings_content| {
2994                    language_settings_field(settings_content, |language| {
2995                        if let Some(prettier) = &language.prettier {
2996                            &prettier.allowed
2997                        } else {
2998                            &None
2999                        }
3000                    })
3001                },
3002                pick_mut: |settings_content| {
3003                    language_settings_field_mut(settings_content, |language| {
3004                        &mut language.prettier.get_or_insert_default().allowed
3005                    })
3006                },
3007            }),
3008            metadata: None,
3009        }),
3010        SettingsPageItem::SettingItem(SettingItem {
3011            title: "Parser",
3012            description: "Forces Prettier integration to use a specific parser name when formatting files with the language",
3013            field: Box::new(SettingField {
3014                pick: |settings_content| {
3015                    language_settings_field(settings_content, |language| {
3016                        if let Some(prettier) = &language.prettier {
3017                            &prettier.parser
3018                        } else {
3019                            &None
3020                        }
3021                    })
3022                },
3023                pick_mut: |settings_content| {
3024                    language_settings_field_mut(settings_content, |language| {
3025                        &mut language.prettier.get_or_insert_default().parser
3026                    })
3027                },
3028            }),
3029            metadata: None,
3030        }),
3031        SettingsPageItem::SettingItem(SettingItem {
3032            title: "Plugins",
3033            description: "Forces Prettier integration to use specific plugins when formatting files with the language",
3034            field: Box::new(
3035                SettingField {
3036                    pick: |settings_content| {
3037                        language_settings_field(settings_content, |language| {
3038                            if let Some(prettier) = &language.prettier {
3039                                &prettier.plugins
3040                            } else {
3041                                &None
3042                            }
3043                        })
3044                    },
3045                    pick_mut: |settings_content| {
3046                        language_settings_field_mut(settings_content, |language| {
3047                            &mut language.prettier.get_or_insert_default().plugins
3048                        })
3049                    },
3050                }
3051                .unimplemented(),
3052            ),
3053            metadata: None,
3054        }),
3055        SettingsPageItem::SettingItem(SettingItem {
3056            title: "Options",
3057            description: "Default Prettier options, in the format as in package.json section for Prettier",
3058            field: Box::new(
3059                SettingField {
3060                    pick: |settings_content| {
3061                        language_settings_field(settings_content, |language| {
3062                            if let Some(prettier) = &language.prettier {
3063                                &prettier.options
3064                            } else {
3065                                &None
3066                            }
3067                        })
3068                    },
3069                    pick_mut: |settings_content| {
3070                        language_settings_field_mut(settings_content, |language| {
3071                            &mut language.prettier.get_or_insert_default().options
3072                        })
3073                    },
3074                }
3075                .unimplemented(),
3076            ),
3077            metadata: None,
3078        }),
3079        SettingsPageItem::SectionHeader("Autoclose"),
3080        SettingsPageItem::SettingItem(SettingItem {
3081            title: "Use Autoclose",
3082            description: "Whether to automatically type closing characters for you. For example, when you type (, Zed will automatically add a closing ) at the correct position",
3083            field: Box::new(SettingField {
3084                pick: |settings_content| {
3085                    language_settings_field(settings_content, |language| &language.use_autoclose)
3086                },
3087                pick_mut: |settings_content| {
3088                    language_settings_field_mut(settings_content, |language| {
3089                        &mut language.use_autoclose
3090                    })
3091                },
3092            }),
3093            metadata: None,
3094        }),
3095        SettingsPageItem::SettingItem(SettingItem {
3096            title: "Use Auto Surround",
3097            description: "Whether to automatically surround text with characters for you. For example, when you select text and type (, Zed will automatically surround text with ()",
3098            field: Box::new(SettingField {
3099                pick: |settings_content| {
3100                    language_settings_field(settings_content, |language| {
3101                        &language.use_auto_surround
3102                    })
3103                },
3104                pick_mut: |settings_content| {
3105                    language_settings_field_mut(settings_content, |language| {
3106                        &mut language.use_auto_surround
3107                    })
3108                },
3109            }),
3110            metadata: None,
3111        }),
3112        SettingsPageItem::SettingItem(SettingItem {
3113            title: "Always Treat Brackets As Autoclosed",
3114            description: "Controls how the editor handles the autoclosed characters. When set to `false`(default), skipping over and auto-removing of the closing characters happen only for auto-inserted characters. Otherwise(when `true`), the closing characters are always skipped over and auto-removed no matter how they were inserted",
3115            field: Box::new(SettingField {
3116                pick: |settings_content| {
3117                    language_settings_field(settings_content, |language| {
3118                        &language.always_treat_brackets_as_autoclosed
3119                    })
3120                },
3121                pick_mut: |settings_content| {
3122                    language_settings_field_mut(settings_content, |language| {
3123                        &mut language.always_treat_brackets_as_autoclosed
3124                    })
3125                },
3126            }),
3127            metadata: None,
3128        }),
3129        SettingsPageItem::SettingItem(SettingItem {
3130            title: "Jsx Tag Auto Close",
3131            description: "Whether to automatically close JSX tags",
3132            field: Box::new(SettingField {
3133                // TODO(settings_ui): this setting should just be a bool
3134                pick: |settings_content| {
3135                    language_settings_field(settings_content, |language| {
3136                        match language.jsx_tag_auto_close.as_ref() {
3137                            Some(s) => &s.enabled,
3138                            None => &None,
3139                        }
3140                    })
3141                },
3142                pick_mut: |settings_content| {
3143                    language_settings_field_mut(settings_content, |language| {
3144                        &mut language.jsx_tag_auto_close.get_or_insert_default().enabled
3145                    })
3146                },
3147            }),
3148            metadata: None,
3149        }),
3150        SettingsPageItem::SectionHeader("LSP"),
3151        SettingsPageItem::SettingItem(SettingItem {
3152            title: "Enable Language Server",
3153            description: "Whether to use language servers to provide code intelligence",
3154            field: Box::new(SettingField {
3155                pick: |settings_content| {
3156                    language_settings_field(settings_content, |language| {
3157                        &language.enable_language_server
3158                    })
3159                },
3160                pick_mut: |settings_content| {
3161                    language_settings_field_mut(settings_content, |language| {
3162                        &mut language.enable_language_server
3163                    })
3164                },
3165            }),
3166            metadata: None,
3167        }),
3168        SettingsPageItem::SettingItem(SettingItem {
3169            title: "Language Servers",
3170            description: "The list of language servers to use (or disable) for this language",
3171            field: Box::new(
3172                SettingField {
3173                    pick: |settings_content| {
3174                        language_settings_field(settings_content, |language| {
3175                            &language.language_servers
3176                        })
3177                    },
3178                    pick_mut: |settings_content| {
3179                        language_settings_field_mut(settings_content, |language| {
3180                            &mut language.language_servers
3181                        })
3182                    },
3183                }
3184                .unimplemented(),
3185            ),
3186            metadata: None,
3187        }),
3188        SettingsPageItem::SettingItem(SettingItem {
3189            title: "Linked Edits",
3190            description: "Whether to perform linked edits of associated ranges, if the language server supports it. For example, when editing opening <html> tag, the contents of the closing </html> tag will be edited as well",
3191            field: Box::new(SettingField {
3192                pick: |settings_content| {
3193                    language_settings_field(settings_content, |language| &language.linked_edits)
3194                },
3195                pick_mut: |settings_content| {
3196                    language_settings_field_mut(settings_content, |language| {
3197                        &mut language.linked_edits
3198                    })
3199                },
3200            }),
3201            metadata: None,
3202        }),
3203        SettingsPageItem::SectionHeader("Edit Predictions"),
3204        SettingsPageItem::SettingItem(SettingItem {
3205            title: "Show Edit Predictions",
3206            description: "Controls whether edit predictions are shown immediately (true) or manually by triggering `editor::ShowEditPrediction` (false)",
3207            field: Box::new(SettingField {
3208                pick: |settings_content| {
3209                    language_settings_field(settings_content, |language| {
3210                        &language.show_edit_predictions
3211                    })
3212                },
3213                pick_mut: |settings_content| {
3214                    language_settings_field_mut(settings_content, |language| {
3215                        &mut language.show_edit_predictions
3216                    })
3217                },
3218            }),
3219            metadata: None,
3220        }),
3221        SettingsPageItem::SettingItem(SettingItem {
3222            title: "Edit Predictions Disabled In",
3223            description: "Controls whether edit predictions are shown in the given language scopes",
3224            field: Box::new(
3225                SettingField {
3226                    pick: |settings_content| {
3227                        language_settings_field(settings_content, |language| {
3228                            &language.edit_predictions_disabled_in
3229                        })
3230                    },
3231                    pick_mut: |settings_content| {
3232                        language_settings_field_mut(settings_content, |language| {
3233                            &mut language.edit_predictions_disabled_in
3234                        })
3235                    },
3236                }
3237                .unimplemented(),
3238            ),
3239            metadata: None,
3240        }),
3241        SettingsPageItem::SectionHeader("Whitespace"),
3242        SettingsPageItem::SettingItem(SettingItem {
3243            title: "Show Whitespaces",
3244            description: "Whether to show tabs and spaces in the editor",
3245            field: Box::new(SettingField {
3246                pick: |settings_content| {
3247                    language_settings_field(settings_content, |language| &language.show_whitespaces)
3248                },
3249                pick_mut: |settings_content| {
3250                    language_settings_field_mut(settings_content, |language| {
3251                        &mut language.show_whitespaces
3252                    })
3253                },
3254            }),
3255            metadata: None,
3256        }),
3257        SettingsPageItem::SettingItem(SettingItem {
3258            title: "Space Whitespace Indicator",
3259            description: "Visible character used to render space characters when show_whitespaces is enabled (default: \"\")",
3260            field: Box::new(
3261                SettingField {
3262                    pick: |settings_content| {
3263                        language_settings_field(settings_content, |language| {
3264                            if let Some(whitespace_map) = &language.whitespace_map {
3265                                &whitespace_map.space
3266                            } else {
3267                                &None
3268                            }
3269                        })
3270                    },
3271                    pick_mut: |settings_content| {
3272                        language_settings_field_mut(settings_content, |language| {
3273                            &mut language.whitespace_map.get_or_insert_default().space
3274                        })
3275                    },
3276                }
3277                .unimplemented(),
3278            ),
3279            metadata: None,
3280        }),
3281        SettingsPageItem::SettingItem(SettingItem {
3282            title: "Tab Whitespace Indicator",
3283            description: "Visible character used to render tab characters when show_whitespaces is enabled (default: \"\")",
3284            field: Box::new(
3285                SettingField {
3286                    pick: |settings_content| {
3287                        language_settings_field(settings_content, |language| {
3288                            if let Some(whitespace_map) = &language.whitespace_map {
3289                                &whitespace_map.tab
3290                            } else {
3291                                &None
3292                            }
3293                        })
3294                    },
3295                    pick_mut: |settings_content| {
3296                        language_settings_field_mut(settings_content, |language| {
3297                            &mut language.whitespace_map.get_or_insert_default().tab
3298                        })
3299                    },
3300                }
3301                .unimplemented(),
3302            ),
3303            metadata: None,
3304        }),
3305        SettingsPageItem::SectionHeader("Completions"),
3306        SettingsPageItem::SettingItem(SettingItem {
3307            title: "Show Completions On Input",
3308            description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
3309            field: Box::new(SettingField {
3310                pick: |settings_content| {
3311                    language_settings_field(settings_content, |language| {
3312                        &language.show_completions_on_input
3313                    })
3314                },
3315                pick_mut: |settings_content| {
3316                    language_settings_field_mut(settings_content, |language| {
3317                        &mut language.show_completions_on_input
3318                    })
3319                },
3320            }),
3321            metadata: None,
3322        }),
3323        SettingsPageItem::SettingItem(SettingItem {
3324            title: "Show Completion Documentation",
3325            description: "Whether to display inline and alongside documentation for items in the completions menu",
3326            field: Box::new(SettingField {
3327                pick: |settings_content| {
3328                    language_settings_field(settings_content, |language| {
3329                        &language.show_completion_documentation
3330                    })
3331                },
3332                pick_mut: |settings_content| {
3333                    language_settings_field_mut(settings_content, |language| {
3334                        &mut language.show_completion_documentation
3335                    })
3336                },
3337            }),
3338            metadata: None,
3339        }),
3340        SettingsPageItem::SettingItem(SettingItem {
3341            title: "Words",
3342            description: "Controls how words are completed",
3343            field: Box::new(SettingField {
3344                pick: |settings_content| {
3345                    language_settings_field(settings_content, |language| {
3346                        if let Some(completions) = &language.completions {
3347                            &completions.words
3348                        } else {
3349                            &None
3350                        }
3351                    })
3352                },
3353                pick_mut: |settings_content| {
3354                    language_settings_field_mut(settings_content, |language| {
3355                        &mut language.completions.get_or_insert_default().words
3356                    })
3357                },
3358            }),
3359            metadata: None,
3360        }),
3361        SettingsPageItem::SettingItem(SettingItem {
3362            title: "Words Min Length",
3363            description: "How many characters has to be in the completions query to automatically show the words-based completions",
3364            field: Box::new(SettingField {
3365                pick: |settings_content| {
3366                    language_settings_field(settings_content, |language| {
3367                        if let Some(completions) = &language.completions {
3368                            &completions.words_min_length
3369                        } else {
3370                            &None
3371                        }
3372                    })
3373                },
3374                pick_mut: |settings_content| {
3375                    language_settings_field_mut(settings_content, |language| {
3376                        &mut language
3377                            .completions
3378                            .get_or_insert_default()
3379                            .words_min_length
3380                    })
3381                },
3382            }),
3383            metadata: None,
3384        }),
3385        SettingsPageItem::SettingItem(SettingItem {
3386            title: "Lsp",
3387            description: "Whether to fetch LSP completions or not",
3388            field: Box::new(SettingField {
3389                pick: |settings_content| {
3390                    language_settings_field(settings_content, |language| {
3391                        if let Some(completions) = &language.completions {
3392                            &completions.lsp
3393                        } else {
3394                            &None
3395                        }
3396                    })
3397                },
3398                pick_mut: |settings_content| {
3399                    language_settings_field_mut(settings_content, |language| {
3400                        &mut language.completions.get_or_insert_default().lsp
3401                    })
3402                },
3403            }),
3404            metadata: None,
3405        }),
3406        SettingsPageItem::SettingItem(SettingItem {
3407            title: "Lsp Fetch Timeout Ms",
3408            description: "When fetching LSP completions, determines how long to wait for a response of a particular server (set to 0 to wait indefinitely)",
3409            field: Box::new(SettingField {
3410                pick: |settings_content| {
3411                    language_settings_field(settings_content, |language| {
3412                        if let Some(completions) = &language.completions {
3413                            &completions.lsp_fetch_timeout_ms
3414                        } else {
3415                            &None
3416                        }
3417                    })
3418                },
3419                pick_mut: |settings_content| {
3420                    language_settings_field_mut(settings_content, |language| {
3421                        &mut language
3422                            .completions
3423                            .get_or_insert_default()
3424                            .lsp_fetch_timeout_ms
3425                    })
3426                },
3427            }),
3428            metadata: None,
3429        }),
3430        SettingsPageItem::SettingItem(SettingItem {
3431            title: "Lsp Insert Mode",
3432            description: "Controls how LSP completions are inserted",
3433            field: Box::new(SettingField {
3434                pick: |settings_content| {
3435                    language_settings_field(settings_content, |language| {
3436                        if let Some(completions) = &language.completions {
3437                            &completions.lsp_insert_mode
3438                        } else {
3439                            &None
3440                        }
3441                    })
3442                },
3443                pick_mut: |settings_content| {
3444                    language_settings_field_mut(settings_content, |language| {
3445                        &mut language.completions.get_or_insert_default().lsp_insert_mode
3446                    })
3447                },
3448            }),
3449            metadata: None,
3450        }),
3451        SettingsPageItem::SectionHeader("Inlay Hints"),
3452        SettingsPageItem::SettingItem(SettingItem {
3453            title: "Enabled",
3454            description: "Global switch to toggle hints on and off",
3455            field: Box::new(SettingField {
3456                pick: |settings_content| {
3457                    language_settings_field(settings_content, |language| {
3458                        if let Some(inlay_hints) = &language.inlay_hints {
3459                            &inlay_hints.enabled
3460                        } else {
3461                            &None
3462                        }
3463                    })
3464                },
3465                pick_mut: |settings_content| {
3466                    language_settings_field_mut(settings_content, |language| {
3467                        &mut language.inlay_hints.get_or_insert_default().enabled
3468                    })
3469                },
3470            }),
3471            metadata: None,
3472        }),
3473        SettingsPageItem::SettingItem(SettingItem {
3474            title: "Show Value Hints",
3475            description: "Global switch to toggle inline values on and off when debugging",
3476            field: Box::new(SettingField {
3477                pick: |settings_content| {
3478                    language_settings_field(settings_content, |language| {
3479                        if let Some(inlay_hints) = &language.inlay_hints {
3480                            &inlay_hints.show_value_hints
3481                        } else {
3482                            &None
3483                        }
3484                    })
3485                },
3486                pick_mut: |settings_content| {
3487                    language_settings_field_mut(settings_content, |language| {
3488                        &mut language
3489                            .inlay_hints
3490                            .get_or_insert_default()
3491                            .show_value_hints
3492                    })
3493                },
3494            }),
3495            metadata: None,
3496        }),
3497        SettingsPageItem::SettingItem(SettingItem {
3498            title: "Show Type Hints",
3499            description: "Whether type hints should be shown",
3500            field: Box::new(SettingField {
3501                pick: |settings_content| {
3502                    language_settings_field(settings_content, |language| {
3503                        if let Some(inlay_hints) = &language.inlay_hints {
3504                            &inlay_hints.show_type_hints
3505                        } else {
3506                            &None
3507                        }
3508                    })
3509                },
3510                pick_mut: |settings_content| {
3511                    language_settings_field_mut(settings_content, |language| {
3512                        &mut language.inlay_hints.get_or_insert_default().show_type_hints
3513                    })
3514                },
3515            }),
3516            metadata: None,
3517        }),
3518        SettingsPageItem::SettingItem(SettingItem {
3519            title: "Show Parameter Hints",
3520            description: "Whether parameter hints should be shown",
3521            field: Box::new(SettingField {
3522                pick: |settings_content| {
3523                    language_settings_field(settings_content, |language| {
3524                        if let Some(inlay_hints) = &language.inlay_hints {
3525                            &inlay_hints.show_parameter_hints
3526                        } else {
3527                            &None
3528                        }
3529                    })
3530                },
3531                pick_mut: |settings_content| {
3532                    language_settings_field_mut(settings_content, |language| {
3533                        &mut language
3534                            .inlay_hints
3535                            .get_or_insert_default()
3536                            .show_parameter_hints
3537                    })
3538                },
3539            }),
3540            metadata: None,
3541        }),
3542        SettingsPageItem::SettingItem(SettingItem {
3543            title: "Show Other Hints",
3544            description: "Whether other hints should be shown",
3545            field: Box::new(SettingField {
3546                pick: |settings_content| {
3547                    language_settings_field(settings_content, |language| {
3548                        if let Some(inlay_hints) = &language.inlay_hints {
3549                            &inlay_hints.show_other_hints
3550                        } else {
3551                            &None
3552                        }
3553                    })
3554                },
3555                pick_mut: |settings_content| {
3556                    language_settings_field_mut(settings_content, |language| {
3557                        &mut language
3558                            .inlay_hints
3559                            .get_or_insert_default()
3560                            .show_other_hints
3561                    })
3562                },
3563            }),
3564            metadata: None,
3565        }),
3566        SettingsPageItem::SettingItem(SettingItem {
3567            title: "Show Background",
3568            description: "Whether to show a background for inlay hints",
3569            field: Box::new(SettingField {
3570                pick: |settings_content| {
3571                    language_settings_field(settings_content, |language| {
3572                        if let Some(inlay_hints) = &language.inlay_hints {
3573                            &inlay_hints.show_background
3574                        } else {
3575                            &None
3576                        }
3577                    })
3578                },
3579                pick_mut: |settings_content| {
3580                    language_settings_field_mut(settings_content, |language| {
3581                        &mut language.inlay_hints.get_or_insert_default().show_background
3582                    })
3583                },
3584            }),
3585            metadata: None,
3586        }),
3587        SettingsPageItem::SettingItem(SettingItem {
3588            title: "Edit Debounce Ms",
3589            description: "Whether or not to debounce inlay hints updates after buffer edits (set to 0 to disable debouncing)",
3590            field: Box::new(SettingField {
3591                pick: |settings_content| {
3592                    language_settings_field(settings_content, |language| {
3593                        if let Some(inlay_hints) = &language.inlay_hints {
3594                            &inlay_hints.edit_debounce_ms
3595                        } else {
3596                            &None
3597                        }
3598                    })
3599                },
3600                pick_mut: |settings_content| {
3601                    language_settings_field_mut(settings_content, |language| {
3602                        &mut language
3603                            .inlay_hints
3604                            .get_or_insert_default()
3605                            .edit_debounce_ms
3606                    })
3607                },
3608            }),
3609            metadata: None,
3610        }),
3611        SettingsPageItem::SettingItem(SettingItem {
3612            title: "Scroll Debounce Ms",
3613            description: "Whether or not to debounce inlay hints updates after buffer scrolls (set to 0 to disable debouncing)",
3614            field: Box::new(SettingField {
3615                pick: |settings_content| {
3616                    language_settings_field(settings_content, |language| {
3617                        if let Some(inlay_hints) = &language.inlay_hints {
3618                            &inlay_hints.scroll_debounce_ms
3619                        } else {
3620                            &None
3621                        }
3622                    })
3623                },
3624                pick_mut: |settings_content| {
3625                    language_settings_field_mut(settings_content, |language| {
3626                        &mut language
3627                            .inlay_hints
3628                            .get_or_insert_default()
3629                            .scroll_debounce_ms
3630                    })
3631                },
3632            }),
3633            metadata: None,
3634        }),
3635        SettingsPageItem::SettingItem(SettingItem {
3636            title: "Toggle On Modifiers Press",
3637            description: "Toggles inlay hints (hides or shows) when the user presses the modifiers specified",
3638            field: Box::new(
3639                SettingField {
3640                    pick: |settings_content| {
3641                        language_settings_field(settings_content, |language| {
3642                            if let Some(inlay_hints) = &language.inlay_hints {
3643                                &inlay_hints.toggle_on_modifiers_press
3644                            } else {
3645                                &None
3646                            }
3647                        })
3648                    },
3649                    pick_mut: |settings_content| {
3650                        language_settings_field_mut(settings_content, |language| {
3651                            &mut language
3652                                .inlay_hints
3653                                .get_or_insert_default()
3654                                .toggle_on_modifiers_press
3655                        })
3656                    },
3657                }
3658                .unimplemented(),
3659            ),
3660            metadata: None,
3661        }),
3662        SettingsPageItem::SectionHeader("Tasks"),
3663        SettingsPageItem::SettingItem(SettingItem {
3664            title: "Enabled",
3665            description: "Whether tasks are enabled for this language",
3666            field: Box::new(SettingField {
3667                pick: |settings_content| {
3668                    language_settings_field(settings_content, |language| {
3669                        if let Some(tasks) = &language.tasks {
3670                            &tasks.enabled
3671                        } else {
3672                            &None
3673                        }
3674                    })
3675                },
3676                pick_mut: |settings_content| {
3677                    language_settings_field_mut(settings_content, |language| {
3678                        &mut language.tasks.get_or_insert_default().enabled
3679                    })
3680                },
3681            }),
3682            metadata: None,
3683        }),
3684        SettingsPageItem::SettingItem(SettingItem {
3685            title: "Variables",
3686            description: "Extra task variables to set for a particular language",
3687            field: Box::new(
3688                SettingField {
3689                    pick: |settings_content| {
3690                        language_settings_field(settings_content, |language| {
3691                            if let Some(tasks) = &language.tasks {
3692                                &tasks.variables
3693                            } else {
3694                                &None
3695                            }
3696                        })
3697                    },
3698                    pick_mut: |settings_content| {
3699                        language_settings_field_mut(settings_content, |language| {
3700                            &mut language.tasks.get_or_insert_default().variables
3701                        })
3702                    },
3703                }
3704                .unimplemented(),
3705            ),
3706            metadata: None,
3707        }),
3708        SettingsPageItem::SettingItem(SettingItem {
3709            title: "Prefer Lsp",
3710            description: "Use LSP tasks over Zed language extension ones",
3711            field: Box::new(SettingField {
3712                pick: |settings_content| {
3713                    language_settings_field(settings_content, |language| {
3714                        if let Some(tasks) = &language.tasks {
3715                            &tasks.prefer_lsp
3716                        } else {
3717                            &None
3718                        }
3719                    })
3720                },
3721                pick_mut: |settings_content| {
3722                    language_settings_field_mut(settings_content, |language| {
3723                        &mut language.tasks.get_or_insert_default().prefer_lsp
3724                    })
3725                },
3726            }),
3727            metadata: None,
3728        }),
3729        SettingsPageItem::SectionHeader("Miscellaneous"),
3730        SettingsPageItem::SettingItem(SettingItem {
3731            title: "Debuggers",
3732            description: "Preferred debuggers for this language",
3733            field: Box::new(
3734                SettingField {
3735                    pick: |settings_content| {
3736                        language_settings_field(settings_content, |language| &language.debuggers)
3737                    },
3738                    pick_mut: |settings_content| {
3739                        language_settings_field_mut(settings_content, |language| {
3740                            &mut language.debuggers
3741                        })
3742                    },
3743                }
3744                .unimplemented(),
3745            ),
3746            metadata: None,
3747        }),
3748        SettingsPageItem::SettingItem(SettingItem {
3749            title: "Extend Comment On Newline",
3750            description: "Whether to start a new line with a comment when a previous line is a comment as well",
3751            field: Box::new(SettingField {
3752                pick: |settings_content| {
3753                    language_settings_field(settings_content, |language| {
3754                        &language.extend_comment_on_newline
3755                    })
3756                },
3757                pick_mut: |settings_content| {
3758                    language_settings_field_mut(settings_content, |language| {
3759                        &mut language.extend_comment_on_newline
3760                    })
3761                },
3762            }),
3763            metadata: None,
3764        }),
3765    ]
3766}