diff --git a/assets/settings/default.json b/assets/settings/default.json index 21d90f17dd..382099e1e8 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -398,7 +398,16 @@ "edit_debounce_ms": 700, // Time to wait after scrolling the buffer, before requesting the hints, // set to 0 to disable debouncing. - "scroll_debounce_ms": 50 + "scroll_debounce_ms": 50, + /// A set of modifiers which, when pressed, will toggle the visibility of inlay hints. + /// If the set if empty or not all the modifiers specified are pressed, inlay hints will not be toggled. + "toggle_on_modifiers_press": { + "control": false, + "shift": false, + "alt": false, + "platform": false, + "function": false + } }, "project_panel": { // Whether to show the project panel button in the status bar diff --git a/crates/collab/src/tests/editor_tests.rs b/crates/collab/src/tests/editor_tests.rs index a094d9cd8c..b034524129 100644 --- a/crates/collab/src/tests/editor_tests.rs +++ b/crates/collab/src/tests/editor_tests.rs @@ -1537,6 +1537,7 @@ async fn test_mutual_editor_inlay_hint_cache_update( show_parameter_hints: false, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); }); @@ -1552,6 +1553,7 @@ async fn test_mutual_editor_inlay_hint_cache_update( show_parameter_hints: false, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); }); @@ -1770,6 +1772,7 @@ async fn test_inlay_hint_refresh_is_forwarded( show_parameter_hints: false, show_other_hints: false, show_background: false, + toggle_on_modifiers_press: None, }) }); }); @@ -1785,6 +1788,7 @@ async fn test_inlay_hint_refresh_is_forwarded( show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 09cbdcf8be..369d499fd2 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -711,6 +711,7 @@ pub struct Editor { edit_prediction_indent_conflict: bool, edit_prediction_requires_modifier_in_indent_conflict: bool, inlay_hint_cache: InlayHintCache, + inlay_hint_modifiers_toggled: bool, next_inlay_id: usize, _subscriptions: Vec, pixel_position_of_newest_cursor: Option>, @@ -1419,6 +1420,7 @@ impl Editor { released_too_fast: false, }, inline_diagnostics_enabled: mode == EditorMode::Full, + inlay_hint_modifiers_toggled: false, inlay_hint_cache: InlayHintCache::new(inlay_hint_settings), gutter_hovered: false, @@ -3691,6 +3693,9 @@ impl Editor { ); let (invalidate_cache, required_languages) = match reason { InlayHintRefreshReason::Toggle(enabled) => { + if self.inlay_hint_cache.enabled == enabled { + return; + } self.inlay_hint_cache.enabled = enabled; if enabled { (InvalidationStrategy::RefreshRequested, None) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 31d0b342b0..46db26b238 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -12,6 +12,7 @@ use crate::{ hover_popover::{ self, hover_at, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH, MIN_POPOVER_LINE_HEIGHT, }, + inlay_hint_settings, items::BufferSearchHighlights, mouse_context_menu::{self, MenuPosition, MouseContextMenu}, scroll::{axis_pair, scroll_amount::ScrollAmount, AxisPair}, @@ -19,10 +20,11 @@ use crate::{ DisplayRow, DocumentHighlightRead, DocumentHighlightWrite, EditDisplayMode, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, ExpandExcerpts, FocusedBlock, GoToHunk, GoToPrevHunk, GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor, - InlineCompletion, JumpData, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point, RowExt, - RowRangeExt, SelectPhase, SelectedTextHighlight, Selection, SoftWrap, StickyHeaderExcerpt, - ToPoint, ToggleFold, COLUMNAR_SELECTION_MODIFIERS, CURSORS_VISIBLE_FOR, FILE_HEADER_HEIGHT, - GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN, MULTI_BUFFER_EXCERPT_HEADER_HEIGHT, + InlayHintRefreshReason, InlineCompletion, JumpData, LineDown, LineUp, OpenExcerpts, PageDown, + PageUp, Point, RowExt, RowRangeExt, SelectPhase, SelectedTextHighlight, Selection, SoftWrap, + StickyHeaderExcerpt, ToPoint, ToggleFold, COLUMNAR_SELECTION_MODIFIERS, CURSORS_VISIBLE_FOR, + FILE_HEADER_HEIGHT, GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN, + MULTI_BUFFER_EXCERPT_HEADER_HEIGHT, }; use buffer_diff::{DiffHunkSecondaryStatus, DiffHunkStatus, DiffHunkStatusKind}; use client::ParticipantIndex; @@ -505,6 +507,30 @@ impl EditorElement { return; } editor.update(cx, |editor, cx| { + let inlay_hint_settings = inlay_hint_settings( + editor.selections.newest_anchor().head(), + &editor.buffer.read(cx).snapshot(cx), + cx, + ); + + if let Some(inlay_modifiers) = + inlay_hint_settings.toggle_on_modifiers_press.as_ref() + { + if inlay_modifiers == &event.modifiers { + editor.refresh_inlay_hints( + InlayHintRefreshReason::Toggle(!editor.inlay_hints_enabled()), + cx, + ); + editor.inlay_hint_modifiers_toggled = true; + } else if editor.inlay_hint_modifiers_toggled { + editor.refresh_inlay_hints( + InlayHintRefreshReason::Toggle(!editor.inlay_hints_enabled()), + cx, + ); + editor.inlay_hint_modifiers_toggled = false; + } + } + if editor.hover_state.focused(window, cx) { return; } diff --git a/crates/editor/src/hover_links.rs b/crates/editor/src/hover_links.rs index b0e4abcb32..694ffad609 100644 --- a/crates/editor/src/hover_links.rs +++ b/crates/editor/src/hover_links.rs @@ -1271,6 +1271,7 @@ mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs index 9df8884965..662a168407 100644 --- a/crates/editor/src/hover_popover.rs +++ b/crates/editor/src/hover_popover.rs @@ -1536,6 +1536,7 @@ mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); diff --git a/crates/editor/src/inlay_hint_cache.rs b/crates/editor/src/inlay_hint_cache.rs index 39186b2b28..bb46dec01f 100644 --- a/crates/editor/src/inlay_hint_cache.rs +++ b/crates/editor/src/inlay_hint_cache.rs @@ -1288,6 +1288,7 @@ pub mod tests { show_parameter_hints: allowed_hint_kinds.contains(&Some(InlayHintKind::Parameter)), show_other_hints: allowed_hint_kinds.contains(&None), show_background: false, + toggle_on_modifiers_press: None, }) }); let (_, editor, fake_server) = prepare_test_objects(cx, |fake_server, file_with_hints| { @@ -1391,6 +1392,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); @@ -1493,6 +1495,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); @@ -1712,6 +1715,7 @@ pub mod tests { show_parameter_hints: allowed_hint_kinds.contains(&Some(InlayHintKind::Parameter)), show_other_hints: allowed_hint_kinds.contains(&None), show_background: false, + toggle_on_modifiers_press: None, }) }); @@ -1871,6 +1875,7 @@ pub mod tests { .contains(&Some(InlayHintKind::Parameter)), show_other_hints: new_allowed_hint_kinds.contains(&None), show_background: false, + toggle_on_modifiers_press: None, }) }); cx.executor().run_until_parked(); @@ -1913,6 +1918,7 @@ pub mod tests { .contains(&Some(InlayHintKind::Parameter)), show_other_hints: another_allowed_hint_kinds.contains(&None), show_background: false, + toggle_on_modifiers_press: None, }) }); cx.executor().run_until_parked(); @@ -1967,6 +1973,7 @@ pub mod tests { .contains(&Some(InlayHintKind::Parameter)), show_other_hints: final_allowed_hint_kinds.contains(&None), show_background: false, + toggle_on_modifiers_press: None, }) }); cx.executor().run_until_parked(); @@ -2038,6 +2045,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); @@ -2169,6 +2177,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); @@ -2467,6 +2476,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); @@ -2811,6 +2821,7 @@ pub mod tests { show_parameter_hints: false, show_other_hints: false, show_background: false, + toggle_on_modifiers_press: None, }) }); @@ -2992,6 +3003,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); cx.executor().run_until_parked(); @@ -3023,6 +3035,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); @@ -3114,6 +3127,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); @@ -3187,6 +3201,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); cx.executor().run_until_parked(); @@ -3246,6 +3261,7 @@ pub mod tests { show_parameter_hints: true, show_other_hints: true, show_background: false, + toggle_on_modifiers_press: None, }) }); diff --git a/crates/gpui/src/platform/keystroke.rs b/crates/gpui/src/platform/keystroke.rs index f2edf35a5a..a81f63c7f2 100644 --- a/crates/gpui/src/platform/keystroke.rs +++ b/crates/gpui/src/platform/keystroke.rs @@ -1,4 +1,5 @@ -use serde::Deserialize; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; use std::{ error::Error, fmt::{Display, Write}, @@ -306,24 +307,29 @@ impl std::fmt::Display for Keystroke { } /// The state of the modifier keys at some point in time -#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, Deserialize, Hash)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, Serialize, Deserialize, Hash, JsonSchema)] pub struct Modifiers { /// The control key + #[serde(default)] pub control: bool, /// The alt key /// Sometimes also known as the 'meta' key + #[serde(default)] pub alt: bool, /// The shift key + #[serde(default)] pub shift: bool, /// The command key, on macos /// the windows key, on windows /// the super key, on linux + #[serde(default)] pub platform: bool, /// The function key + #[serde(default)] pub function: bool, } diff --git a/crates/language/src/language_settings.rs b/crates/language/src/language_settings.rs index 3adb8a8156..bd4132c06a 100644 --- a/crates/language/src/language_settings.rs +++ b/crates/language/src/language_settings.rs @@ -9,7 +9,7 @@ use ec4rs::{ Properties as EditorconfigProperties, }; use globset::{Glob, GlobMatcher, GlobSet, GlobSetBuilder}; -use gpui::App; +use gpui::{App, Modifiers}; use itertools::{Either, Itertools}; use schemars::{ schema::{InstanceType, ObjectValidation, Schema, SchemaObject, SingleOrVec}, @@ -905,6 +905,13 @@ pub struct InlayHintSettings { /// Default: 50 #[serde(default = "scroll_debounce_ms")] pub scroll_debounce_ms: u64, + /// Toggles inlay hints (hides or shows) when the user presses the modifiers specified. + /// If only a subset of the modifiers specified is pressed, hints are not toggled. + /// If no modifiers are specified, this is equivalent to `None`. + /// + /// Default: None + #[serde(default)] + pub toggle_on_modifiers_press: Option, } fn edit_debounce_ms() -> u64 { diff --git a/docs/src/configuring-zed.md b/docs/src/configuring-zed.md index 74ec806d69..32cab6593e 100644 --- a/docs/src/configuring-zed.md +++ b/docs/src/configuring-zed.md @@ -1517,7 +1517,8 @@ To interpret all `.c` files as C++, files called `MyLockFile` as TOML and files "show_other_hints": true, "show_background": false, "edit_debounce_ms": 700, - "scroll_debounce_ms": 50 + "scroll_debounce_ms": 50, + "toggle_on_modifiers_press": null } ``` @@ -1539,6 +1540,22 @@ Use the `lsp` section for the server configuration. Examples are provided in the Hints are not instantly queried in Zed, two kinds of debounces are used, either may be set to 0 to be disabled. Settings-related hint updates are not debounced. +All possible config values for `toggle_on_modifiers_press` are: + +```json +"inlay_hints": { + "toggle_on_modifiers_press": { + "control": true, + "shift": true, + "alt": true, + "platform": true, + "function": true + } +} +``` + +Unspecified values have a `false` value, hints won't be toggled if all the modifiers are `false` or not all the modifiers are pressed. + ## Journal - Description: Configuration for the journal.