refactor: encoding
in EncodingIndicator
is now an optional trait object
feat: Add all supported encodings, and open the encoding selector when an action(save or reopen) is chosen.
This commit is contained in:
parent
5723987b59
commit
5fec768e37
8 changed files with 221 additions and 60 deletions
0
..gitignore.swp
Normal file
0
..gitignore.swp
Normal file
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -5272,6 +5272,7 @@ name = "encodings"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"editor",
|
"editor",
|
||||||
|
"encoding",
|
||||||
"fuzzy",
|
"fuzzy",
|
||||||
"gpui",
|
"gpui",
|
||||||
"picker",
|
"picker",
|
||||||
|
@ -20516,6 +20517,7 @@ dependencies = [
|
||||||
"diagnostics",
|
"diagnostics",
|
||||||
"edit_prediction_button",
|
"edit_prediction_button",
|
||||||
"editor",
|
"editor",
|
||||||
|
"encoding",
|
||||||
"encodings",
|
"encodings",
|
||||||
"env_logger 0.11.8",
|
"env_logger 0.11.8",
|
||||||
"extension",
|
"extension",
|
||||||
|
|
|
@ -12,6 +12,7 @@ picker.workspace = true
|
||||||
util.workspace = true
|
util.workspace = true
|
||||||
fuzzy.workspace = true
|
fuzzy.workspace = true
|
||||||
editor.workspace = true
|
editor.workspace = true
|
||||||
|
encoding = "0.2.33"
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
@ -1,28 +1,16 @@
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use gpui::{ClickEvent, Entity, WeakEntity};
|
use encoding::Encoding;
|
||||||
|
use gpui::{ClickEvent, Entity, Subscription, WeakEntity};
|
||||||
use ui::{Button, ButtonCommon, Context, LabelSize, Render, Tooltip, Window, div};
|
use ui::{Button, ButtonCommon, Context, LabelSize, Render, Tooltip, Window, div};
|
||||||
use ui::{Clickable, ParentElement};
|
use ui::{Clickable, ParentElement};
|
||||||
use workspace::{ItemHandle, StatusItemView, Workspace};
|
use workspace::{ItemHandle, StatusItemView, Workspace};
|
||||||
|
|
||||||
use crate::selectors::save_or_reopen::{EncodingSaveOrReopenSelector, get_current_encoding};
|
use crate::selectors::save_or_reopen::{EncodingSaveOrReopenSelector, get_current_encoding};
|
||||||
|
|
||||||
pub enum Encoding {
|
|
||||||
Utf8,
|
|
||||||
Iso8859_1,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encoding {
|
|
||||||
pub fn as_str(&self) -> &str {
|
|
||||||
match &self {
|
|
||||||
Encoding::Utf8 => "UTF-8",
|
|
||||||
Encoding::Iso8859_1 => "ISO 8859-1",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct EncodingIndicator {
|
pub struct EncodingIndicator {
|
||||||
pub encoding: Encoding,
|
pub encoding: Option<&'static dyn Encoding>,
|
||||||
pub workspace: WeakEntity<Workspace>,
|
pub workspace: WeakEntity<Workspace>,
|
||||||
|
observe: Option<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod selectors;
|
pub mod selectors;
|
||||||
|
@ -49,14 +37,51 @@ impl Render for EncodingIndicator {
|
||||||
|
|
||||||
impl EncodingIndicator {
|
impl EncodingIndicator {
|
||||||
pub fn get_current_encoding(&self, cx: &mut Context<Self>, editor: WeakEntity<Editor>) {}
|
pub fn get_current_encoding(&self, cx: &mut Context<Self>, editor: WeakEntity<Editor>) {}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
encoding: Option<&'static dyn encoding::Encoding>,
|
||||||
|
workspace: WeakEntity<Workspace>,
|
||||||
|
observe: Option<Subscription>,
|
||||||
|
) -> EncodingIndicator {
|
||||||
|
EncodingIndicator {
|
||||||
|
encoding,
|
||||||
|
workspace,
|
||||||
|
observe,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(
|
||||||
|
&mut self,
|
||||||
|
editor: Entity<Editor>,
|
||||||
|
_: &mut Window,
|
||||||
|
cx: &mut Context<EncodingIndicator>,
|
||||||
|
) {
|
||||||
|
let editor = editor.read(cx);
|
||||||
|
if let Some((_, buffer, _)) = editor.active_excerpt(cx) {
|
||||||
|
let encoding = buffer.read(cx).encoding;
|
||||||
|
self.encoding = Some(encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StatusItemView for EncodingIndicator {
|
impl StatusItemView for EncodingIndicator {
|
||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&mut self,
|
&mut self,
|
||||||
_active_pane_item: Option<&dyn ItemHandle>,
|
active_pane_item: Option<&dyn ItemHandle>,
|
||||||
_window: &mut Window,
|
window: &mut Window,
|
||||||
_cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
|
match active_pane_item.and_then(|item| item.downcast::<Editor>()) {
|
||||||
|
Some(editor) => {
|
||||||
|
self.observe = Some(cx.observe_in(&editor, window, Self::update));
|
||||||
|
self.update(editor, window, cx);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.encoding = None;
|
||||||
|
self.observe = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,31 +3,49 @@ pub mod save_or_reopen {
|
||||||
use gpui::{AppContext, ParentElement};
|
use gpui::{AppContext, ParentElement};
|
||||||
use picker::Picker;
|
use picker::Picker;
|
||||||
use picker::PickerDelegate;
|
use picker::PickerDelegate;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||||
use gpui::{DismissEvent, Entity, EventEmitter, Focusable, WeakEntity};
|
use gpui::{DismissEvent, Entity, EventEmitter, Focusable, WeakEntity};
|
||||||
|
|
||||||
use ui::{Context, Label, ListItem, Render, Window, rems, v_flex};
|
use ui::{Context, HighlightedLabel, Label, ListItem, Render, Window, rems, v_flex};
|
||||||
use workspace::{ModalView, Workspace};
|
use workspace::{ModalView, Workspace};
|
||||||
|
|
||||||
|
use crate::selectors::encoding::{Action, EncodingSelector, EncodingSelectorDelegate};
|
||||||
|
|
||||||
pub struct EncodingSaveOrReopenSelector {
|
pub struct EncodingSaveOrReopenSelector {
|
||||||
picker: Entity<Picker<EncodingSaveOrReopenDelegate>>,
|
picker: Entity<Picker<EncodingSaveOrReopenDelegate>>,
|
||||||
|
pub current_selection: usize,
|
||||||
|
workspace: WeakEntity<Workspace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EncodingSaveOrReopenSelector {
|
impl EncodingSaveOrReopenSelector {
|
||||||
pub fn new(window: &mut Window, cx: &mut Context<EncodingSaveOrReopenSelector>) -> Self {
|
pub fn new(
|
||||||
let delegate = EncodingSaveOrReopenDelegate::new(cx.entity().downgrade());
|
window: &mut Window,
|
||||||
|
cx: &mut Context<EncodingSaveOrReopenSelector>,
|
||||||
|
workspace: WeakEntity<Workspace>,
|
||||||
|
) -> Self {
|
||||||
|
let delegate =
|
||||||
|
EncodingSaveOrReopenDelegate::new(cx.entity().downgrade(), workspace.clone());
|
||||||
|
|
||||||
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
||||||
|
|
||||||
Self { picker }
|
Self {
|
||||||
|
picker,
|
||||||
|
current_selection: 0,
|
||||||
|
workspace,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle(workspace: &mut Workspace, window: &mut Window, cx: &mut Context<Workspace>) {
|
pub fn toggle(workspace: &mut Workspace, window: &mut Window, cx: &mut Context<Workspace>) {
|
||||||
|
let weak_workspace = workspace.weak_handle();
|
||||||
workspace.toggle_modal(window, cx, |window, cx| {
|
workspace.toggle_modal(window, cx, |window, cx| {
|
||||||
EncodingSaveOrReopenSelector::new(window, cx)
|
EncodingSaveOrReopenSelector::new(window, cx, weak_workspace)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,28 +71,57 @@ pub mod save_or_reopen {
|
||||||
impl EventEmitter<DismissEvent> for EncodingSaveOrReopenSelector {}
|
impl EventEmitter<DismissEvent> for EncodingSaveOrReopenSelector {}
|
||||||
|
|
||||||
pub struct EncodingSaveOrReopenDelegate {
|
pub struct EncodingSaveOrReopenDelegate {
|
||||||
encoding_selector: WeakEntity<EncodingSaveOrReopenSelector>,
|
selector: WeakEntity<EncodingSaveOrReopenSelector>,
|
||||||
current_selection: usize,
|
current_selection: usize,
|
||||||
matches: Vec<StringMatch>,
|
matches: Vec<StringMatch>,
|
||||||
pub actions: Vec<StringMatchCandidate>,
|
pub actions: Vec<StringMatchCandidate>,
|
||||||
|
workspace: WeakEntity<Workspace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EncodingSaveOrReopenDelegate {
|
impl EncodingSaveOrReopenDelegate {
|
||||||
pub fn new(selector: WeakEntity<EncodingSaveOrReopenSelector>) -> Self {
|
pub fn new(
|
||||||
|
selector: WeakEntity<EncodingSaveOrReopenSelector>,
|
||||||
|
workspace: WeakEntity<Workspace>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
encoding_selector: selector,
|
selector,
|
||||||
current_selection: 0,
|
current_selection: 0,
|
||||||
matches: Vec::new(),
|
matches: Vec::new(),
|
||||||
actions: vec![
|
actions: vec![
|
||||||
StringMatchCandidate::new(0, "Save with encoding"),
|
StringMatchCandidate::new(0, "Save with encoding"),
|
||||||
StringMatchCandidate::new(1, "Reopen with encoding"),
|
StringMatchCandidate::new(1, "Reopen with encoding"),
|
||||||
],
|
],
|
||||||
|
workspace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_actions(&self) -> (&str, &str) {
|
pub fn get_actions(&self) -> (&str, &str) {
|
||||||
(&self.actions[0].string, &self.actions[1].string)
|
(&self.actions[0].string, &self.actions[1].string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn post_selection(
|
||||||
|
&self,
|
||||||
|
cx: &mut Context<Picker<EncodingSaveOrReopenDelegate>>,
|
||||||
|
window: &mut Window,
|
||||||
|
) {
|
||||||
|
if self.current_selection == 0 {
|
||||||
|
if let Some(workspace) = self.workspace.upgrade() {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
workspace.toggle_modal(window, cx, |window, cx| {
|
||||||
|
EncodingSelector::new(window, cx, Action::Save)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if self.current_selection == 1 {
|
||||||
|
if let Some(workspace) = self.workspace.upgrade() {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
workspace.toggle_modal(window, cx, |window, cx| {
|
||||||
|
EncodingSelector::new(window, cx, Action::Reopen)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PickerDelegate for EncodingSaveOrReopenDelegate {
|
impl PickerDelegate for EncodingSaveOrReopenDelegate {
|
||||||
|
@ -92,9 +139,14 @@ pub mod save_or_reopen {
|
||||||
&mut self,
|
&mut self,
|
||||||
ix: usize,
|
ix: usize,
|
||||||
_window: &mut Window,
|
_window: &mut Window,
|
||||||
_cx: &mut Context<Picker<Self>>,
|
cx: &mut Context<Picker<Self>>,
|
||||||
) {
|
) {
|
||||||
self.current_selection = ix;
|
self.current_selection = ix;
|
||||||
|
self.selector
|
||||||
|
.update(cx, |selector, cx| {
|
||||||
|
selector.current_selection = ix;
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn placeholder_text(&self, _window: &mut Window, _cx: &mut ui::App) -> std::sync::Arc<str> {
|
fn placeholder_text(&self, _window: &mut Window, _cx: &mut ui::App) -> std::sync::Arc<str> {
|
||||||
|
@ -137,24 +189,31 @@ pub mod save_or_reopen {
|
||||||
|
|
||||||
this.update(cx, |picker, cx| {
|
this.update(cx, |picker, cx| {
|
||||||
let delegate = &mut picker.delegate;
|
let delegate = &mut picker.delegate;
|
||||||
delegate.current_selection = matches.len().saturating_sub(1);
|
|
||||||
delegate.matches = matches;
|
delegate.matches = matches;
|
||||||
|
delegate.current_selection = delegate
|
||||||
|
.current_selection
|
||||||
|
.min(delegate.matches.len().saturating_sub(1));
|
||||||
|
delegate
|
||||||
|
.selector
|
||||||
|
.update(cx, |selector, cx| {
|
||||||
|
selector.current_selection = delegate.current_selection
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
.log_err();
|
.log_err();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm(
|
fn confirm(&mut self, _: bool, window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||||
&mut self,
|
self.dismissed(window, cx);
|
||||||
secondary: bool,
|
if self.selector.is_upgradable() {
|
||||||
window: &mut Window,
|
self.post_selection(cx, window);
|
||||||
cx: &mut Context<Picker<Self>>,
|
}
|
||||||
) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dismissed(&mut self, _window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
fn dismissed(&mut self, _window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||||
self.encoding_selector
|
self.selector
|
||||||
.update(cx, |_, cx| cx.emit(DismissEvent))
|
.update(cx, |_, cx| cx.emit(DismissEvent))
|
||||||
.log_err();
|
.log_err();
|
||||||
}
|
}
|
||||||
|
@ -162,11 +221,18 @@ pub mod save_or_reopen {
|
||||||
fn render_match(
|
fn render_match(
|
||||||
&self,
|
&self,
|
||||||
ix: usize,
|
ix: usize,
|
||||||
selected: bool,
|
_: bool,
|
||||||
window: &mut Window,
|
_: &mut Window,
|
||||||
cx: &mut Context<Picker<Self>>,
|
_: &mut Context<Picker<Self>>,
|
||||||
) -> Option<Self::ListItem> {
|
) -> Option<Self::ListItem> {
|
||||||
Some(ListItem::new(ix).child(Label::new(&self.matches[ix].string)))
|
Some(
|
||||||
|
ListItem::new(ix)
|
||||||
|
.child(HighlightedLabel::new(
|
||||||
|
&self.matches[ix].string,
|
||||||
|
self.matches[ix].positions.clone(),
|
||||||
|
))
|
||||||
|
.spacing(ui::ListItemSpacing::Sparse),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,19 +242,28 @@ pub mod save_or_reopen {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod encoding {
|
pub mod encoding {
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::{
|
||||||
|
ops::DerefMut,
|
||||||
|
rc::{Rc, Weak},
|
||||||
|
sync::{Arc, atomic::AtomicBool},
|
||||||
|
};
|
||||||
|
|
||||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AppContext, BackgroundExecutor, DismissEvent, Entity, EventEmitter, Focusable, WeakEntity,
|
AppContext, BackgroundExecutor, DismissEvent, Entity, EventEmitter, Focusable, Length,
|
||||||
|
WeakEntity, actions,
|
||||||
};
|
};
|
||||||
use picker::{Picker, PickerDelegate};
|
use picker::{Picker, PickerDelegate};
|
||||||
use ui::{Context, Label, ListItem, ParentElement, Render, Styled, Window, rems, v_flex};
|
use ui::{
|
||||||
|
Context, DefiniteLength, HighlightedLabel, Label, ListItem, ListItemSpacing, ParentElement,
|
||||||
|
Render, Styled, Window, rems, v_flex,
|
||||||
|
};
|
||||||
use util::{ResultExt, TryFutureExt};
|
use util::{ResultExt, TryFutureExt};
|
||||||
use workspace::{ModalView, Workspace};
|
use workspace::{ModalView, Workspace};
|
||||||
|
|
||||||
pub struct EncodingSelector {
|
pub struct EncodingSelector {
|
||||||
pub picker: Entity<Picker<EncodingSelectorDelegate>>,
|
picker: Entity<Picker<EncodingSelectorDelegate>>,
|
||||||
|
action: Action,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EncodingSelectorDelegate {
|
pub struct EncodingSelectorDelegate {
|
||||||
|
@ -204,7 +279,44 @@ pub mod encoding {
|
||||||
current_selection: 0,
|
current_selection: 0,
|
||||||
encodings: vec![
|
encodings: vec![
|
||||||
StringMatchCandidate::new(0, "UTF-8"),
|
StringMatchCandidate::new(0, "UTF-8"),
|
||||||
StringMatchCandidate::new(1, "ISO 8859-1"),
|
StringMatchCandidate::new(1, "UTF-16 LE"),
|
||||||
|
StringMatchCandidate::new(2, "UTF-16 BE"),
|
||||||
|
StringMatchCandidate::new(3, "IBM866"),
|
||||||
|
StringMatchCandidate::new(4, "ISO 8859-1"),
|
||||||
|
StringMatchCandidate::new(5, "ISO 8859-2"),
|
||||||
|
StringMatchCandidate::new(6, "ISO 8859-3"),
|
||||||
|
StringMatchCandidate::new(7, "ISO 8859-4"),
|
||||||
|
StringMatchCandidate::new(8, "ISO 8859-5"),
|
||||||
|
StringMatchCandidate::new(9, "ISO 8859-6"),
|
||||||
|
StringMatchCandidate::new(10, "ISO 8859-7"),
|
||||||
|
StringMatchCandidate::new(11, "ISO 8859-8"),
|
||||||
|
StringMatchCandidate::new(12, "ISO 8859-10"),
|
||||||
|
StringMatchCandidate::new(13, "ISO 8859-13"),
|
||||||
|
StringMatchCandidate::new(14, "ISO 8859-14"),
|
||||||
|
StringMatchCandidate::new(15, "ISO 8859-15"),
|
||||||
|
StringMatchCandidate::new(16, "ISO 8859-16"),
|
||||||
|
StringMatchCandidate::new(17, "KOI8-R"),
|
||||||
|
StringMatchCandidate::new(18, "KOI8-U"),
|
||||||
|
StringMatchCandidate::new(19, "MacRoman"),
|
||||||
|
StringMatchCandidate::new(20, "Mac Cyrillic"),
|
||||||
|
StringMatchCandidate::new(21, "Windows-874"),
|
||||||
|
StringMatchCandidate::new(22, "Windows-1250"),
|
||||||
|
StringMatchCandidate::new(23, "Windows-1251"),
|
||||||
|
StringMatchCandidate::new(24, "Windows-1252"),
|
||||||
|
StringMatchCandidate::new(25, "Windows-1253"),
|
||||||
|
StringMatchCandidate::new(26, "Windows-1254"),
|
||||||
|
StringMatchCandidate::new(27, "Windows-1255"),
|
||||||
|
StringMatchCandidate::new(28, "Windows-1256"),
|
||||||
|
StringMatchCandidate::new(29, "Windows-1257"),
|
||||||
|
StringMatchCandidate::new(30, "Windows-1258"),
|
||||||
|
StringMatchCandidate::new(31, "EUC-KR"),
|
||||||
|
StringMatchCandidate::new(32, "EUC-JP"),
|
||||||
|
StringMatchCandidate::new(33, "Shift_JIS"),
|
||||||
|
StringMatchCandidate::new(34, "ISO 2022-JP"),
|
||||||
|
StringMatchCandidate::new(35, "GBK"),
|
||||||
|
StringMatchCandidate::new(36, "GB18030"),
|
||||||
|
StringMatchCandidate::new(37, "Big5"),
|
||||||
|
StringMatchCandidate::new(38, "HZ-GB-2312"),
|
||||||
],
|
],
|
||||||
matches: Vec::new(),
|
matches: Vec::new(),
|
||||||
selector,
|
selector,
|
||||||
|
@ -244,7 +356,6 @@ pub mod encoding {
|
||||||
) -> gpui::Task<()> {
|
) -> gpui::Task<()> {
|
||||||
let executor = cx.background_executor().clone();
|
let executor = cx.background_executor().clone();
|
||||||
let encodings = self.encodings.clone();
|
let encodings = self.encodings.clone();
|
||||||
let current_selection = self.current_selection;
|
|
||||||
|
|
||||||
cx.spawn_in(window, async move |picker, cx| {
|
cx.spawn_in(window, async move |picker, cx| {
|
||||||
let matches: Vec<StringMatch>;
|
let matches: Vec<StringMatch>;
|
||||||
|
@ -264,14 +375,25 @@ pub mod encoding {
|
||||||
matches = fuzzy::match_strings(
|
matches = fuzzy::match_strings(
|
||||||
&encodings,
|
&encodings,
|
||||||
&query,
|
&query,
|
||||||
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
38,
|
||||||
0,
|
|
||||||
&AtomicBool::new(false),
|
&AtomicBool::new(false),
|
||||||
executor,
|
executor,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
picker
|
||||||
|
.update(cx, |picker, cx| {
|
||||||
|
let delegate = &mut picker.delegate;
|
||||||
|
delegate.matches = matches;
|
||||||
|
delegate.current_selection = delegate
|
||||||
|
.current_selection
|
||||||
|
.min(delegate.matches.len().saturating_sub(1));
|
||||||
|
cx.notify();
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,20 +418,32 @@ pub mod encoding {
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Picker<Self>>,
|
cx: &mut Context<Picker<Self>>,
|
||||||
) -> Option<Self::ListItem> {
|
) -> Option<Self::ListItem> {
|
||||||
Some(ListItem::new(ix).child(Label::new(&self.matches[ix].string)))
|
Some(
|
||||||
|
ListItem::new(ix)
|
||||||
|
.child(HighlightedLabel::new(
|
||||||
|
&self.matches[ix].string,
|
||||||
|
self.matches[ix].positions.clone(),
|
||||||
|
))
|
||||||
|
.spacing(ListItemSpacing::Sparse),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Action {
|
||||||
|
Save,
|
||||||
|
Reopen,
|
||||||
|
}
|
||||||
|
|
||||||
impl EncodingSelector {
|
impl EncodingSelector {
|
||||||
pub fn new(window: &mut Window, cx: &mut Context<EncodingSelector>) -> EncodingSelector {
|
pub fn new(
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<EncodingSelector>,
|
||||||
|
action: Action,
|
||||||
|
) -> EncodingSelector {
|
||||||
let delegate = EncodingSelectorDelegate::new(cx.entity().downgrade());
|
let delegate = EncodingSelectorDelegate::new(cx.entity().downgrade());
|
||||||
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
||||||
|
|
||||||
EncodingSelector { picker: picker }
|
EncodingSelector { picker, action }
|
||||||
}
|
|
||||||
|
|
||||||
pub fn toggle(workspace: &mut Workspace, window: &mut Window, cx: &mut Context<Workspace>) {
|
|
||||||
workspace.toggle_modal(window, cx, |window, cx| EncodingSelector::new(window, cx));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ pub struct Buffer {
|
||||||
has_unsaved_edits: Cell<(clock::Global, bool)>,
|
has_unsaved_edits: Cell<(clock::Global, bool)>,
|
||||||
change_bits: Vec<rc::Weak<Cell<bool>>>,
|
change_bits: Vec<rc::Weak<Cell<bool>>>,
|
||||||
_subscriptions: Vec<gpui::Subscription>,
|
_subscriptions: Vec<gpui::Subscription>,
|
||||||
encoding: &'static dyn encoding::Encoding,
|
pub encoding: &'static dyn encoding::Encoding,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
|
|
@ -168,6 +168,7 @@ zed_actions.workspace = true
|
||||||
zeta.workspace = true
|
zeta.workspace = true
|
||||||
zlog.workspace = true
|
zlog.workspace = true
|
||||||
zlog_settings.workspace = true
|
zlog_settings.workspace = true
|
||||||
|
encoding = "0.2.33"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
windows.workspace = true
|
windows.workspace = true
|
||||||
|
|
|
@ -397,10 +397,8 @@ pub fn initialize_workspace(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let encoding_indicator = cx.new(|_cx| encodings::EncodingIndicator {
|
let encoding_indicator =
|
||||||
encoding: encodings::Encoding::Utf8,
|
cx.new(|_cx| encodings::EncodingIndicator::new(None, workspace.weak_handle(), None));
|
||||||
workspace: workspace_handle.downgrade(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let cursor_position =
|
let cursor_position =
|
||||||
cx.new(|_| go_to_line::cursor_position::CursorPosition::new(workspace));
|
cx.new(|_| go_to_line::cursor_position::CursorPosition::new(workspace));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue