Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion assets/settings/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,9 @@
// Whether to show the active language button in the status bar.
"active_language_button": true,
// Whether to show the cursor position button in the status bar.
"cursor_position_button": true
"cursor_position_button": true,
// Whether to show active line endings button in the status bar.
"line_endings_button": false
},
// Settings specific to the terminal
"terminal": {
Expand Down
70 changes: 70 additions & 0 deletions crates/line_ending_selector/src/line_ending_indicator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use editor::Editor;
use gpui::{Entity, Subscription, WeakEntity};
use language::LineEnding;
use ui::{Tooltip, prelude::*};
use workspace::{StatusBarSettings, StatusItemView, item::ItemHandle, item::Settings};

use crate::{LineEndingSelector, Toggle};

#[derive(Default)]
pub struct LineEndingIndicator {
line_ending: Option<LineEnding>,
active_editor: Option<WeakEntity<Editor>>,
_observe_active_editor: Option<Subscription>,
}

impl LineEndingIndicator {
fn update(&mut self, editor: Entity<Editor>, _: &mut Window, cx: &mut Context<Self>) {
self.line_ending = None;
self.active_editor = None;

if let Some((_, buffer, _)) = editor.read(cx).active_excerpt(cx) {
let line_ending = buffer.read(cx).line_ending();
self.line_ending = Some(line_ending);
self.active_editor = Some(editor.downgrade());
}

cx.notify();
}
}

impl Render for LineEndingIndicator {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
if !StatusBarSettings::get_global(cx).line_endings_button {
return div();
}

div().when_some(self.line_ending.as_ref(), |el, line_ending| {
el.child(
Button::new("change-line-ending", line_ending.label())
.label_size(LabelSize::Small)
.on_click(cx.listener(|this, _, window, cx| {
if let Some(editor) = this.active_editor.as_ref() {
LineEndingSelector::toggle(editor, window, cx);
}
}))
.tooltip(|window, cx| {
Tooltip::for_action("Select Line Ending", &Toggle, window, cx)
}),
)
})
}
}

impl StatusItemView for LineEndingIndicator {
fn set_active_pane_item(
&mut self,
active_pane_item: Option<&dyn ItemHandle>,
window: &mut Window,
cx: &mut Context<Self>,
) {
if let Some(editor) = active_pane_item.and_then(|item| item.downcast::<Editor>()) {
self._observe_active_editor = Some(cx.observe_in(&editor, window, Self::update));
self.update(editor, window, cx);
} else {
self.line_ending = None;
self._observe_active_editor = None;
}
cx.notify();
}
}
10 changes: 5 additions & 5 deletions crates/line_ending_selector/src/line_ending_selector.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
mod line_ending_indicator;

use editor::Editor;
use gpui::{DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, Task, WeakEntity, actions};
use language::{Buffer, LineEnding};
pub use line_ending_indicator::LineEndingIndicator;
use picker::{Picker, PickerDelegate};
use project::Project;
use std::sync::Arc;
Expand All @@ -9,7 +12,7 @@ use util::ResultExt;
use workspace::ModalView;

actions!(
line_ending,
line_ending_selector,
[
/// Toggles the line ending selector modal.
Toggle
Expand Down Expand Up @@ -172,10 +175,7 @@ impl PickerDelegate for LineEndingSelectorDelegate {
_: &mut Context<Picker<Self>>,
) -> Option<Self::ListItem> {
let line_ending = self.matches.get(ix)?;
let label = match line_ending {
LineEnding::Unix => "LF",
LineEnding::Windows => "CRLF",
};
let label = line_ending.label();

let mut list_item = ListItem::new(ix)
.inset(true)
Expand Down
4 changes: 4 additions & 0 deletions crates/settings/src/settings_content/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,10 @@ pub struct StatusBarSettingsContent {
///
/// Default: true
pub cursor_position_button: Option<bool>,
/// Whether to show active line endings button in the status bar.
///
/// Default: false
pub line_endings_button: Option<bool>,
}

#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom)]
Expand Down
7 changes: 7 additions & 0 deletions crates/text/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3261,6 +3261,13 @@ impl LineEnding {
}
}

pub fn label(&self) -> &'static str {
match self {
LineEnding::Unix => "LF",
LineEnding::Windows => "CRLF",
}
}

pub fn detect(text: &str) -> Self {
let mut max_ix = cmp::min(text.len(), 1000);
while !text.is_char_boundary(max_ix) {
Expand Down
2 changes: 2 additions & 0 deletions crates/workspace/src/workspace_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ pub struct StatusBarSettings {
pub show: bool,
pub active_language_button: bool,
pub cursor_position_button: bool,
pub line_endings_button: bool,
}

impl Settings for StatusBarSettings {
Expand All @@ -236,6 +237,7 @@ impl Settings for StatusBarSettings {
show: status_bar.show.unwrap(),
active_language_button: status_bar.active_language_button.unwrap(),
cursor_position_button: status_bar.cursor_position_button.unwrap(),
line_endings_button: status_bar.line_endings_button.unwrap(),
}
}

Expand Down
5 changes: 4 additions & 1 deletion crates/zed/src/zed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,8 @@ pub fn initialize_workspace(

let cursor_position =
cx.new(|_| go_to_line::cursor_position::CursorPosition::new(workspace));
let line_ending_indicator =
cx.new(|_| line_ending_selector::LineEndingIndicator::default());
workspace.status_bar().update(cx, |status_bar, cx| {
status_bar.add_left_item(search_button, window, cx);
status_bar.add_left_item(lsp_button, window, cx);
Expand All @@ -427,6 +429,7 @@ pub fn initialize_workspace(
status_bar.add_right_item(edit_prediction_button, window, cx);
status_bar.add_right_item(active_buffer_language, window, cx);
status_bar.add_right_item(active_toolchain_language, window, cx);
status_bar.add_right_item(line_ending_indicator, window, cx);
status_bar.add_right_item(vim_mode_indicator, window, cx);
status_bar.add_right_item(cursor_position, window, cx);
status_bar.add_right_item(image_info, window, cx);
Expand Down Expand Up @@ -4619,7 +4622,7 @@ mod tests {
"keymap_editor",
"keystroke_input",
"language_selector",
"line_ending",
"line_ending_selector",
"lsp_tool",
"markdown",
"menu",
Expand Down
3 changes: 2 additions & 1 deletion docs/src/configuring-zed.md
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,8 @@ Positive `integer` value between 1 and 32. Values outside of this range will be
```json
"status_bar": {
"active_language_button": true,
"cursor_position_button": true
"cursor_position_button": true,
"line_endings_button": false
},
```

Expand Down
4 changes: 4 additions & 0 deletions docs/src/visual-customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ TBD: Centered layout related settings
// Clicking the button brings up an input for jumping to a line and column.
// Defaults to true.
"cursor_position_button": true,
// Show/hide a button that displays the buffer's line-ending mode.
// Clicking the button brings up the line-ending selector.
// Defaults to false.
"line_endings_button": false
},
"global_lsp_settings": {
// Show/hide the LSP button in the status bar.
Expand Down
Loading