Merge 42e3a6036f
into 64b14ef848
This commit is contained in:
commit
eefa6c7ea3
10 changed files with 387 additions and 1 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -9474,6 +9474,21 @@ dependencies = [
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "line_ending_selector"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"editor",
|
||||||
|
"fuzzy",
|
||||||
|
"gpui",
|
||||||
|
"language",
|
||||||
|
"picker",
|
||||||
|
"ui",
|
||||||
|
"util",
|
||||||
|
"workspace",
|
||||||
|
"workspace-hack",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "link-cplusplus"
|
name = "link-cplusplus"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
|
@ -20468,6 +20483,7 @@ dependencies = [
|
||||||
"language_tools",
|
"language_tools",
|
||||||
"languages",
|
"languages",
|
||||||
"libc",
|
"libc",
|
||||||
|
"line_ending_selector",
|
||||||
"livekit_client",
|
"livekit_client",
|
||||||
"log",
|
"log",
|
||||||
"markdown",
|
"markdown",
|
||||||
|
|
|
@ -96,6 +96,7 @@ members = [
|
||||||
"crates/language_selector",
|
"crates/language_selector",
|
||||||
"crates/language_tools",
|
"crates/language_tools",
|
||||||
"crates/languages",
|
"crates/languages",
|
||||||
|
"crates/line_ending_selector",
|
||||||
"crates/livekit_api",
|
"crates/livekit_api",
|
||||||
"crates/livekit_client",
|
"crates/livekit_client",
|
||||||
"crates/lmstudio",
|
"crates/lmstudio",
|
||||||
|
@ -321,6 +322,7 @@ language_models = { path = "crates/language_models" }
|
||||||
language_selector = { path = "crates/language_selector" }
|
language_selector = { path = "crates/language_selector" }
|
||||||
language_tools = { path = "crates/language_tools" }
|
language_tools = { path = "crates/language_tools" }
|
||||||
languages = { path = "crates/languages" }
|
languages = { path = "crates/languages" }
|
||||||
|
line_ending_selector = { path = "crates/line_ending_selector" }
|
||||||
livekit_api = { path = "crates/livekit_api" }
|
livekit_api = { path = "crates/livekit_api" }
|
||||||
livekit_client = { path = "crates/livekit_client" }
|
livekit_client = { path = "crates/livekit_client" }
|
||||||
lmstudio = { path = "crates/lmstudio" }
|
lmstudio = { path = "crates/lmstudio" }
|
||||||
|
|
|
@ -121,6 +121,7 @@ pub struct Buffer {
|
||||||
completion_triggers_timestamp: clock::Lamport,
|
completion_triggers_timestamp: clock::Lamport,
|
||||||
deferred_ops: OperationQueue<Operation>,
|
deferred_ops: OperationQueue<Operation>,
|
||||||
capability: Capability,
|
capability: Capability,
|
||||||
|
has_unsaved_line_ending_change: Option<LineEnding>,
|
||||||
has_conflict: bool,
|
has_conflict: bool,
|
||||||
/// Memoize calls to has_changes_since(saved_version).
|
/// Memoize calls to has_changes_since(saved_version).
|
||||||
/// The contents of a cell are (self.version, has_changes) at the time of a last call.
|
/// The contents of a cell are (self.version, has_changes) at the time of a last call.
|
||||||
|
@ -955,6 +956,7 @@ impl Buffer {
|
||||||
completion_triggers_per_language_server: Default::default(),
|
completion_triggers_per_language_server: Default::default(),
|
||||||
completion_triggers_timestamp: Default::default(),
|
completion_triggers_timestamp: Default::default(),
|
||||||
deferred_ops: OperationQueue::new(),
|
deferred_ops: OperationQueue::new(),
|
||||||
|
has_unsaved_line_ending_change: None,
|
||||||
has_conflict: false,
|
has_conflict: false,
|
||||||
change_bits: Default::default(),
|
change_bits: Default::default(),
|
||||||
_subscriptions: Vec::new(),
|
_subscriptions: Vec::new(),
|
||||||
|
@ -1242,6 +1244,19 @@ impl Buffer {
|
||||||
self.syntax_map.lock().language_registry()
|
self.syntax_map.lock().language_registry()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Assign the line ending type to the buffer.
|
||||||
|
pub fn set_line_ending(&mut self, line_ending: LineEnding) {
|
||||||
|
self.text.set_line_ending(line_ending);
|
||||||
|
self.has_unsaved_line_ending_change = if let Some(unsaved_line_ending) =
|
||||||
|
self.has_unsaved_line_ending_change
|
||||||
|
&& unsaved_line_ending != line_ending
|
||||||
|
{
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(line_ending)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Assign the buffer a new [`Capability`].
|
/// Assign the buffer a new [`Capability`].
|
||||||
pub fn set_capability(&mut self, capability: Capability, cx: &mut Context<Self>) {
|
pub fn set_capability(&mut self, capability: Capability, cx: &mut Context<Self>) {
|
||||||
self.capability = capability;
|
self.capability = capability;
|
||||||
|
@ -1259,6 +1274,7 @@ impl Buffer {
|
||||||
self.has_unsaved_edits
|
self.has_unsaved_edits
|
||||||
.set((self.saved_version().clone(), false));
|
.set((self.saved_version().clone(), false));
|
||||||
self.has_conflict = false;
|
self.has_conflict = false;
|
||||||
|
self.has_unsaved_line_ending_change = None;
|
||||||
self.saved_mtime = mtime;
|
self.saved_mtime = mtime;
|
||||||
self.was_changed();
|
self.was_changed();
|
||||||
cx.emit(BufferEvent::Saved);
|
cx.emit(BufferEvent::Saved);
|
||||||
|
@ -1965,7 +1981,7 @@ impl Buffer {
|
||||||
if self.capability == Capability::ReadOnly {
|
if self.capability == Capability::ReadOnly {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if self.has_conflict {
|
if self.has_conflict || self.has_unsaved_line_ending_change.is_some() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
match self.file.as_ref().map(|f| f.disk_state()) {
|
match self.file.as_ref().map(|f| f.disk_state()) {
|
||||||
|
|
24
crates/line_ending_selector/Cargo.toml
Normal file
24
crates/line_ending_selector/Cargo.toml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[package]
|
||||||
|
name = "line_ending_selector"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition.workspace = true
|
||||||
|
publish.workspace = true
|
||||||
|
license = "GPL-3.0-or-later"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/line_ending_selector.rs"
|
||||||
|
doctest = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
editor.workspace = true
|
||||||
|
fuzzy.workspace = true
|
||||||
|
gpui.workspace = true
|
||||||
|
language.workspace = true
|
||||||
|
picker.workspace = true
|
||||||
|
ui.workspace = true
|
||||||
|
util.workspace = true
|
||||||
|
workspace.workspace = true
|
||||||
|
workspace-hack.workspace = true
|
1
crates/line_ending_selector/LICENSE-GPL
Symbolic link
1
crates/line_ending_selector/LICENSE-GPL
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../LICENSE-GPL
|
87
crates/line_ending_selector/src/active_buffer_line_ending.rs
Normal file
87
crates/line_ending_selector/src/active_buffer_line_ending.rs
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
use editor::Editor;
|
||||||
|
use gpui::{Entity, Subscription, WeakEntity};
|
||||||
|
use language::LineEnding;
|
||||||
|
use ui::{Tooltip, prelude::*};
|
||||||
|
use workspace::{ItemHandle, StatusItemView, Workspace};
|
||||||
|
|
||||||
|
use crate::{LineEndingSelector, Toggle};
|
||||||
|
|
||||||
|
pub struct ActiveBufferLineEnding {
|
||||||
|
active_line_ending: Option<LineEnding>,
|
||||||
|
workspace: WeakEntity<Workspace>,
|
||||||
|
_observe_active_editor: Option<Subscription>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveBufferLineEnding {
|
||||||
|
pub fn new(workspace: &Workspace) -> Self {
|
||||||
|
Self {
|
||||||
|
active_line_ending: None,
|
||||||
|
workspace: workspace.weak_handle(),
|
||||||
|
_observe_active_editor: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_line_ending(
|
||||||
|
&mut self,
|
||||||
|
editor: Entity<Editor>,
|
||||||
|
_: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
let editor = editor.read(cx);
|
||||||
|
if let Some((_, buffer, _)) = editor.active_excerpt(cx) {
|
||||||
|
let line_ending = buffer.read(cx).line_ending();
|
||||||
|
self.active_line_ending = Some(line_ending);
|
||||||
|
}
|
||||||
|
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for ActiveBufferLineEnding {
|
||||||
|
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
div().when_some(
|
||||||
|
self.active_line_ending.as_ref(),
|
||||||
|
|el, active_line_ending| {
|
||||||
|
let active_line_ending_text = match active_line_ending {
|
||||||
|
LineEnding::Unix => "LF",
|
||||||
|
LineEnding::Windows => "CRLF",
|
||||||
|
};
|
||||||
|
|
||||||
|
el.child(
|
||||||
|
Button::new("change-line-ending", active_line_ending_text)
|
||||||
|
.label_size(LabelSize::Small)
|
||||||
|
.on_click(cx.listener(|this, _, window, cx| {
|
||||||
|
if let Some(workspace) = this.workspace.upgrade() {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
LineEndingSelector::toggle(workspace, window, cx)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.tooltip(|window, cx| {
|
||||||
|
Tooltip::for_action("Select Line Ending", &Toggle, window, cx)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StatusItemView for ActiveBufferLineEnding {
|
||||||
|
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_line_ending));
|
||||||
|
self.update_line_ending(editor, window, cx);
|
||||||
|
} else {
|
||||||
|
self.active_line_ending = None;
|
||||||
|
self._observe_active_editor = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}
|
234
crates/line_ending_selector/src/line_ending_selector.rs
Normal file
234
crates/line_ending_selector/src/line_ending_selector.rs
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
mod active_buffer_line_ending;
|
||||||
|
|
||||||
|
pub use active_buffer_line_ending::ActiveBufferLineEnding;
|
||||||
|
use editor::Editor;
|
||||||
|
use fuzzy::{StringMatch, StringMatchCandidate, match_strings};
|
||||||
|
use gpui::{DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, WeakEntity, actions};
|
||||||
|
use language::{Buffer, LineEnding};
|
||||||
|
use picker::{Picker, PickerDelegate};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use ui::{HighlightedLabel, ListItem, ListItemSpacing, prelude::*};
|
||||||
|
use util::ResultExt;
|
||||||
|
use workspace::{ModalView, Workspace};
|
||||||
|
|
||||||
|
actions!(
|
||||||
|
line_ending_selector,
|
||||||
|
[
|
||||||
|
/// Toggles the line ending selector modal.
|
||||||
|
Toggle
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub fn init(cx: &mut App) {
|
||||||
|
cx.observe_new(LineEndingSelector::register).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LineEndingSelector {
|
||||||
|
picker: Entity<Picker<LineEndingSelectorDelegate>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LineEndingSelector {
|
||||||
|
fn register(
|
||||||
|
workspace: &mut Workspace,
|
||||||
|
_window: Option<&mut Window>,
|
||||||
|
_: &mut Context<Workspace>,
|
||||||
|
) {
|
||||||
|
workspace.register_action(move |workspace, _: &Toggle, window, cx| {
|
||||||
|
Self::toggle(workspace, window, cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toggle(
|
||||||
|
workspace: &mut Workspace,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Workspace>,
|
||||||
|
) -> Option<()> {
|
||||||
|
let (_, buffer, _) = workspace
|
||||||
|
.active_item(cx)?
|
||||||
|
.act_as::<Editor>(cx)?
|
||||||
|
.read(cx)
|
||||||
|
.active_excerpt(cx)?;
|
||||||
|
|
||||||
|
workspace.toggle_modal(window, cx, move |window, cx| {
|
||||||
|
LineEndingSelector::new(buffer, window, cx)
|
||||||
|
});
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new(buffer: Entity<Buffer>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
|
let line_ending = buffer.read(cx).line_ending();
|
||||||
|
let delegate =
|
||||||
|
LineEndingSelectorDelegate::new(cx.entity().downgrade(), buffer, line_ending);
|
||||||
|
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
||||||
|
Self { picker }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for LineEndingSelector {
|
||||||
|
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
v_flex().w(rems(34.)).child(self.picker.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Focusable for LineEndingSelector {
|
||||||
|
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||||
|
self.picker.focus_handle(cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventEmitter<DismissEvent> for LineEndingSelector {}
|
||||||
|
impl ModalView for LineEndingSelector {}
|
||||||
|
|
||||||
|
struct LineEndingSelectorDelegate {
|
||||||
|
line_ending_selector: WeakEntity<LineEndingSelector>,
|
||||||
|
buffer: Entity<Buffer>,
|
||||||
|
line_ending: LineEnding,
|
||||||
|
matches: Vec<StringMatch>,
|
||||||
|
selected_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LineEndingSelectorDelegate {
|
||||||
|
fn new(
|
||||||
|
line_ending_selector: WeakEntity<LineEndingSelector>,
|
||||||
|
buffer: Entity<Buffer>,
|
||||||
|
line_ending: LineEnding,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
line_ending_selector,
|
||||||
|
buffer,
|
||||||
|
line_ending,
|
||||||
|
matches: vec![],
|
||||||
|
selected_index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PickerDelegate for LineEndingSelectorDelegate {
|
||||||
|
type ListItem = ListItem;
|
||||||
|
|
||||||
|
fn placeholder_text(&self, _window: &mut Window, _cx: &mut App) -> Arc<str> {
|
||||||
|
"Select a line ending…".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_count(&self) -> usize {
|
||||||
|
self.matches.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn confirm(&mut self, _: bool, window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||||
|
if let Some(mat) = self.matches.get(self.selected_index) {
|
||||||
|
let buffer = self.buffer.downgrade();
|
||||||
|
let line_ending = match mat.candidate_id {
|
||||||
|
0 => LineEnding::Unix,
|
||||||
|
1 => LineEnding::Windows,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
buffer
|
||||||
|
.update(cx, |this, _| {
|
||||||
|
this.set_line_ending(line_ending);
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
|
}
|
||||||
|
self.dismissed(window, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dismissed(&mut self, _: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||||
|
self.line_ending_selector
|
||||||
|
.update(cx, |_, cx| cx.emit(DismissEvent))
|
||||||
|
.log_err();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn selected_index(&self) -> usize {
|
||||||
|
self.selected_index
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_selected_index(
|
||||||
|
&mut self,
|
||||||
|
ix: usize,
|
||||||
|
_window: &mut Window,
|
||||||
|
_: &mut Context<Picker<Self>>,
|
||||||
|
) {
|
||||||
|
self.selected_index = ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_matches(
|
||||||
|
&mut self,
|
||||||
|
query: String,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Picker<Self>>,
|
||||||
|
) -> gpui::Task<()> {
|
||||||
|
let background = cx.background_executor().clone();
|
||||||
|
cx.spawn_in(window, async move |this, cx| {
|
||||||
|
let matches = if query.is_empty() {
|
||||||
|
vec![
|
||||||
|
StringMatch {
|
||||||
|
candidate_id: 0,
|
||||||
|
string: "LF".to_string(),
|
||||||
|
positions: Vec::new(),
|
||||||
|
score: 0.0,
|
||||||
|
},
|
||||||
|
StringMatch {
|
||||||
|
candidate_id: 1,
|
||||||
|
string: "CRLF".to_string(),
|
||||||
|
positions: Vec::new(),
|
||||||
|
score: 0.0,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
match_strings(
|
||||||
|
&[
|
||||||
|
StringMatchCandidate::new(0, "LF"),
|
||||||
|
StringMatchCandidate::new(1, "CRLF"),
|
||||||
|
],
|
||||||
|
&query,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
2,
|
||||||
|
&Default::default(),
|
||||||
|
background,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
};
|
||||||
|
|
||||||
|
this.update(cx, |this, cx| {
|
||||||
|
let delegate = &mut this.delegate;
|
||||||
|
delegate.matches = matches;
|
||||||
|
delegate.selected_index = delegate
|
||||||
|
.selected_index
|
||||||
|
.min(delegate.matches.len().saturating_sub(1));
|
||||||
|
cx.notify();
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_match(
|
||||||
|
&self,
|
||||||
|
ix: usize,
|
||||||
|
selected: bool,
|
||||||
|
_: &mut Window,
|
||||||
|
_: &mut Context<Picker<Self>>,
|
||||||
|
) -> Option<Self::ListItem> {
|
||||||
|
let mat = &self.matches[ix];
|
||||||
|
let line_ending = match mat.candidate_id {
|
||||||
|
0 => LineEnding::Unix,
|
||||||
|
1 => LineEnding::Windows,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
let label = match line_ending {
|
||||||
|
LineEnding::Unix => "LF",
|
||||||
|
LineEnding::Windows => "CRLF",
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut list_item = ListItem::new(ix)
|
||||||
|
.inset(true)
|
||||||
|
.spacing(ListItemSpacing::Sparse)
|
||||||
|
.toggle_state(selected)
|
||||||
|
.child(HighlightedLabel::new(label, mat.positions.clone()));
|
||||||
|
|
||||||
|
if self.line_ending == line_ending {
|
||||||
|
list_item = list_item.end_slot(Icon::new(IconName::Check).color(Color::Muted));
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(list_item)
|
||||||
|
}
|
||||||
|
}
|
|
@ -93,6 +93,7 @@ language_models.workspace = true
|
||||||
language_selector.workspace = true
|
language_selector.workspace = true
|
||||||
language_tools.workspace = true
|
language_tools.workspace = true
|
||||||
languages = { workspace = true, features = ["load-grammars"] }
|
languages = { workspace = true, features = ["load-grammars"] }
|
||||||
|
line_ending_selector.workspace = true
|
||||||
libc.workspace = true
|
libc.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
markdown.workspace = true
|
markdown.workspace = true
|
||||||
|
|
|
@ -618,6 +618,7 @@ pub fn main() {
|
||||||
terminal_view::init(cx);
|
terminal_view::init(cx);
|
||||||
journal::init(app_state.clone(), cx);
|
journal::init(app_state.clone(), cx);
|
||||||
language_selector::init(cx);
|
language_selector::init(cx);
|
||||||
|
line_ending_selector::init(cx);
|
||||||
toolchain_selector::init(cx);
|
toolchain_selector::init(cx);
|
||||||
theme_selector::init(cx);
|
theme_selector::init(cx);
|
||||||
settings_profile_selector::init(cx);
|
settings_profile_selector::init(cx);
|
||||||
|
|
|
@ -385,6 +385,8 @@ pub fn initialize_workspace(
|
||||||
cx.new(|_| language_selector::ActiveBufferLanguage::new(workspace));
|
cx.new(|_| language_selector::ActiveBufferLanguage::new(workspace));
|
||||||
let active_toolchain_language =
|
let active_toolchain_language =
|
||||||
cx.new(|cx| toolchain_selector::ActiveToolchain::new(workspace, window, cx));
|
cx.new(|cx| toolchain_selector::ActiveToolchain::new(workspace, window, cx));
|
||||||
|
let active_buffer_line_ending =
|
||||||
|
cx.new(|_| line_ending_selector::ActiveBufferLineEnding::new(workspace));
|
||||||
let vim_mode_indicator = cx.new(|cx| vim::ModeIndicator::new(window, cx));
|
let vim_mode_indicator = cx.new(|cx| vim::ModeIndicator::new(window, cx));
|
||||||
let image_info = cx.new(|_cx| ImageInfo::new(workspace));
|
let image_info = cx.new(|_cx| ImageInfo::new(workspace));
|
||||||
|
|
||||||
|
@ -407,6 +409,7 @@ pub fn initialize_workspace(
|
||||||
status_bar.add_right_item(edit_prediction_button, window, cx);
|
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_buffer_language, window, cx);
|
||||||
status_bar.add_right_item(active_toolchain_language, window, cx);
|
status_bar.add_right_item(active_toolchain_language, window, cx);
|
||||||
|
status_bar.add_right_item(active_buffer_line_ending, window, cx);
|
||||||
status_bar.add_right_item(vim_mode_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(cursor_position, window, cx);
|
||||||
status_bar.add_right_item(image_info, window, cx);
|
status_bar.add_right_item(image_info, window, cx);
|
||||||
|
@ -4471,6 +4474,7 @@ mod tests {
|
||||||
"keymap_editor",
|
"keymap_editor",
|
||||||
"keystroke_input",
|
"keystroke_input",
|
||||||
"language_selector",
|
"language_selector",
|
||||||
|
"line_ending_selector",
|
||||||
"lsp_tool",
|
"lsp_tool",
|
||||||
"markdown",
|
"markdown",
|
||||||
"menu",
|
"menu",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue