From 39e0e26d1dde01c4e372bf0d47b5b9780fa9d71e Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 10 Apr 2024 12:08:07 +0200 Subject: [PATCH] Line numbers short mode (#10354) Followup to #10327 It can be enabled with the following setting: "line_indicator_format": "short" No release note, as the original change didn't go out to Preview yet. /cc @bartekpacia @0x2CA Release Notes: - N/A --- Cargo.lock | 4 ++ assets/settings/default.json | 9 +++- crates/go_to_line/Cargo.toml | 4 ++ crates/go_to_line/src/cursor_position.rs | 57 +++++++++++++++++++++--- crates/go_to_line/src/go_to_line.rs | 3 ++ 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 573d5c28fb..ed70eb8af7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4375,6 +4375,7 @@ dependencies = [ name = "go_to_line" version = "0.1.0" dependencies = [ + "anyhow", "editor", "gpui", "indoc", @@ -4382,7 +4383,10 @@ dependencies = [ "menu", "project", "rope", + "schemars", + "serde", "serde_json", + "settings", "text", "theme", "tree-sitter-rust", diff --git a/assets/settings/default.json b/assets/settings/default.json index 879fdce6d0..9d834389d1 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -626,5 +626,12 @@ "task": { // Whether to show task status indicator in the status bar. Default: true "show_status_indicator": true - } + }, + // Whether to show full labels in line indicator or short ones + // + // Values: + // - `short`: "2 s, 15 l, 32 c" + // - `long`: "2 selections, 15 lines, 32 characters" + // Default: long + "line_indicator_format": "long" } diff --git a/crates/go_to_line/Cargo.toml b/crates/go_to_line/Cargo.toml index a697242523..0e19b41b75 100644 --- a/crates/go_to_line/Cargo.toml +++ b/crates/go_to_line/Cargo.toml @@ -13,9 +13,13 @@ path = "src/go_to_line.rs" doctest = false [dependencies] +anyhow.workspace = true editor.workspace = true gpui.workspace = true menu.workspace = true +schemars.workspace = true +serde.workspace = true +settings.workspace = true text.workspace = true theme.workspace = true ui.workspace = true diff --git a/crates/go_to_line/src/cursor_position.rs b/crates/go_to_line/src/cursor_position.rs index ee2d4d86c8..420cb858e6 100644 --- a/crates/go_to_line/src/cursor_position.rs +++ b/crates/go_to_line/src/cursor_position.rs @@ -1,5 +1,8 @@ use editor::{Editor, ToPoint}; -use gpui::{Subscription, View, WeakView}; +use gpui::{AppContext, Subscription, View, WeakView}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use settings::{Settings, SettingsSources}; use std::fmt::Write; use text::{Point, Selection}; use ui::{ @@ -51,7 +54,10 @@ impl CursorPosition { } for selection in editor.selections.all::(cx) { if selection.end != selection.start { - self.selected_count.lines += (selection.end.row - selection.start.row + 1) as usize; + self.selected_count.lines += (selection.end.row - selection.start.row) as usize; + if selection.end.column != 0 { + self.selected_count.lines += 1; + } } } self.position = last_selection.map(|s| s.head().to_point(&buffer)); @@ -59,7 +65,7 @@ impl CursorPosition { cx.notify(); } - fn write_position(&self, text: &mut String) { + fn write_position(&self, text: &mut String, cx: &AppContext) { if self.selected_count <= (SelectionStats { selections: 1, @@ -74,6 +80,8 @@ impl CursorPosition { characters, selections, } = self.selected_count; + let format = LineIndicatorFormat::get(None, cx); + let is_short_format = format == &LineIndicatorFormat::Short; let lines = (lines > 1).then_some((lines, "line")); let selections = (selections > 1).then_some((selections, "selection")); let characters = (characters > 0).then_some((characters, "character")); @@ -87,7 +95,12 @@ impl CursorPosition { if wrote_once { write!(text, ", ").unwrap(); } - let plural_suffix = if count > 1 { "s" } else { "" }; + let name = if is_short_format { &name[..1] } else { &name }; + let plural_suffix = if count > 1 && !is_short_format { + "s" + } else { + "" + }; write!(text, "{count} {name}{plural_suffix}").unwrap(); wrote_once = true; } @@ -103,7 +116,7 @@ impl Render for CursorPosition { position.row + 1, position.column + 1 ); - self.write_position(&mut text); + self.write_position(&mut text, cx); el.child( Button::new("go-to-line-column", text) @@ -144,3 +157,37 @@ impl StatusItemView for CursorPosition { cx.notify(); } } + +#[derive(Clone, Copy, Default, PartialEq, JsonSchema, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +pub(crate) enum LineIndicatorFormat { + Short, + #[default] + Long, +} + +/// Whether or not to automatically check for updates. +/// +/// Values: short, long +/// Default: short +#[derive(Clone, Copy, Default, JsonSchema, Deserialize, Serialize)] +#[serde(transparent)] +pub(crate) struct LineIndicatorFormatContent(LineIndicatorFormat); + +impl Settings for LineIndicatorFormat { + const KEY: Option<&'static str> = Some("line_indicator_format"); + + type FileContent = Option; + + fn load( + sources: SettingsSources, + _: &mut AppContext, + ) -> anyhow::Result { + let format = [sources.release_channel, sources.user] + .into_iter() + .find_map(|value| value.copied().flatten()) + .unwrap_or(sources.default.ok_or_else(Self::missing_default)?); + + Ok(format.0) + } +} diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 4c34468df4..1ea492a8eb 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -1,10 +1,12 @@ pub mod cursor_position; +use cursor_position::LineIndicatorFormat; use editor::{scroll::Autoscroll, Editor}; use gpui::{ actions, div, prelude::*, AnyWindowHandle, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView, Render, SharedString, Styled, Subscription, View, ViewContext, VisualContext, }; +use settings::Settings; use text::{Bias, Point}; use theme::ActiveTheme; use ui::{h_flex, prelude::*, v_flex, Label}; @@ -14,6 +16,7 @@ use workspace::ModalView; actions!(go_to_line, [Toggle]); pub fn init(cx: &mut AppContext) { + LineIndicatorFormat::register(cx); cx.observe_new_views(GoToLine::register).detach(); }