From 43357f689c69d9ae9e93f00bcf77d99552d642a6 Mon Sep 17 00:00:00 2001 From: R Aadarsh Date: Sun, 24 Aug 2025 20:34:33 +0530 Subject: [PATCH] Make the status bar encoding indicator update the encoding when an encoding from the selector is chosen. --- Cargo.lock | 1 + crates/encodings/Cargo.toml | 1 + crates/encodings/src/lib.rs | 100 +++++++++++++++++++++++++++++- crates/encodings/src/selectors.rs | 55 ++++++++++++---- 4 files changed, 144 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0002c8be84..18b606eb24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5275,6 +5275,7 @@ dependencies = [ "encoding", "fuzzy", "gpui", + "language", "picker", "ui", "util", diff --git a/crates/encodings/Cargo.toml b/crates/encodings/Cargo.toml index 4b8d877a3a..70b11dd545 100644 --- a/crates/encodings/Cargo.toml +++ b/crates/encodings/Cargo.toml @@ -13,6 +13,7 @@ util.workspace = true fuzzy.workspace = true editor.workspace = true encoding = "0.2.33" +language.workspace = true [lints] workspace = true diff --git a/crates/encodings/src/lib.rs b/crates/encodings/src/lib.rs index 6387919770..169b4bf350 100644 --- a/crates/encodings/src/lib.rs +++ b/crates/encodings/src/lib.rs @@ -1,5 +1,12 @@ use editor::Editor; use encoding::Encoding; +use encoding::all::{ + BIG5_2003, EUC_JP, GB18030, GBK, HZ, IBM866, ISO_2022_JP, ISO_8859_1, ISO_8859_2, ISO_8859_3, + ISO_8859_4, ISO_8859_5, ISO_8859_6, ISO_8859_7, ISO_8859_8, ISO_8859_10, ISO_8859_13, + ISO_8859_14, ISO_8859_15, ISO_8859_16, KOI8_R, KOI8_U, MAC_CYRILLIC, MAC_ROMAN, UTF_8, + UTF_16BE, UTF_16LE, WINDOWS_874, WINDOWS_949, WINDOWS_1250, WINDOWS_1251, WINDOWS_1252, + WINDOWS_1253, WINDOWS_1254, WINDOWS_1255, WINDOWS_1256, WINDOWS_1257, WINDOWS_1258, +}; use gpui::{ClickEvent, Entity, Subscription, WeakEntity}; use ui::{Button, ButtonCommon, Context, LabelSize, Render, Tooltip, Window, div}; use ui::{Clickable, ParentElement}; @@ -20,7 +27,7 @@ impl Render for EncodingIndicator { let status_element = div(); status_element.child( - Button::new("encoding", get_current_encoding()) + Button::new("encoding", encoding_name(self.encoding.unwrap_or(UTF_8))) .label_size(LabelSize::Small) .tooltip(Tooltip::text("Select Encoding")) .on_click(cx.listener(|indicator, _: &ClickEvent, window, cx| { @@ -85,3 +92,94 @@ impl StatusItemView for EncodingIndicator { } } } + +pub fn encoding_name(encoding: &'static dyn Encoding) -> String { + let name = encoding.name(); + + match () { + () if name == UTF_8.name() => "UTF-8", + () if name == UTF_16LE.name() => "UTF-16 LE", + () if name == UTF_16BE.name() => "UTF-16 BE", + () if name == IBM866.name() => "IBM866", + () if name == ISO_8859_1.name() => "ISO 8859-1", + () if name == ISO_8859_2.name() => "ISO 8859-2", + () if name == ISO_8859_3.name() => "ISO 8859-3", + () if name == ISO_8859_4.name() => "ISO 8859-4", + () if name == ISO_8859_5.name() => "ISO 8859-5", + () if name == ISO_8859_6.name() => "ISO 8859-6", + () if name == ISO_8859_7.name() => "ISO 8859-7", + () if name == ISO_8859_8.name() => "ISO 8859-8", + () if name == ISO_8859_10.name() => "ISO 8859-10", + () if name == ISO_8859_13.name() => "ISO 8859-13", + () if name == ISO_8859_14.name() => "ISO 8859-14", + () if name == ISO_8859_15.name() => "ISO 8859-15", + () if name == ISO_8859_16.name() => "ISO 8859-16", + () if name == KOI8_R.name() => "KOI8-R", + () if name == KOI8_U.name() => "KOI8-U", + () if name == MAC_ROMAN.name() => "MacRoman", + () if name == MAC_CYRILLIC.name() => "Mac Cyrillic", + () if name == WINDOWS_874.name() => "Windows-874", + () if name == WINDOWS_1250.name() => "Windows-1250", + () if name == WINDOWS_1251.name() => "Windows-1251", + () if name == WINDOWS_1252.name() => "Windows-1252", + () if name == WINDOWS_1253.name() => "Windows-1253", + () if name == WINDOWS_1254.name() => "Windows-1254", + () if name == WINDOWS_1255.name() => "Windows-1255", + () if name == WINDOWS_1256.name() => "Windows-1256", + () if name == WINDOWS_1257.name() => "Windows-1257", + () if name == WINDOWS_1258.name() => "Windows-1258", + () if name == WINDOWS_949.name() => "Windows-949", + () if name == EUC_JP.name() => "EUC-JP", + () if name == ISO_2022_JP.name() => "ISO 2022-JP", + () if name == GBK.name() => "GBK", + () if name == GB18030.name() => "GB18030", + () if name == BIG5_2003.name() => "Big5", + () if name == HZ.name() => "HZ-GB-2312", + _ => "", + } + .to_string() +} + +pub fn encoding_from_index(index: usize) -> &'static dyn Encoding { + match index { + 0 => UTF_8, + 1 => UTF_16LE, + 2 => UTF_16BE, + 3 => IBM866, + 4 => ISO_8859_1, + 5 => ISO_8859_2, + 6 => ISO_8859_3, + 7 => ISO_8859_4, + 8 => ISO_8859_5, + 9 => ISO_8859_6, + 10 => ISO_8859_7, + 11 => ISO_8859_8, + 12 => ISO_8859_10, + 13 => ISO_8859_13, + 14 => ISO_8859_14, + 15 => ISO_8859_15, + 16 => ISO_8859_16, + 17 => KOI8_R, + 18 => KOI8_U, + 19 => MAC_ROMAN, + 20 => MAC_CYRILLIC, + 21 => WINDOWS_874, + 22 => WINDOWS_1250, + 23 => WINDOWS_1251, + 24 => WINDOWS_1252, + 25 => WINDOWS_1253, + 26 => WINDOWS_1254, + 27 => WINDOWS_1255, + 28 => WINDOWS_1256, + 29 => WINDOWS_1257, + 30 => WINDOWS_1258, + 31 => WINDOWS_949, + 32 => EUC_JP, + 33 => ISO_2022_JP, + 34 => GBK, + 35 => GB18030, + 36 => BIG5_2003, + 37 => HZ, + _ => UTF_8, + } +} diff --git a/crates/encodings/src/selectors.rs b/crates/encodings/src/selectors.rs index fd06c518ef..cdc0702e53 100644 --- a/crates/encodings/src/selectors.rs +++ b/crates/encodings/src/selectors.rs @@ -1,4 +1,5 @@ pub mod save_or_reopen { + use editor::Editor; use gpui::Styled; use gpui::{AppContext, ParentElement}; use picker::Picker; @@ -103,24 +104,40 @@ pub mod save_or_reopen { &self, cx: &mut Context>, window: &mut Window, - ) { + ) -> Option<()> { if self.current_selection == 0 { if let Some(workspace) = self.workspace.upgrade() { + let (_, buffer, _) = workspace + .read(cx) + .active_item(cx)? + .act_as::(cx)? + .read(cx) + .active_excerpt(cx)?; + workspace.update(cx, |workspace, cx| { workspace.toggle_modal(window, cx, |window, cx| { - EncodingSelector::new(window, cx, Action::Save) + EncodingSelector::new(window, cx, Action::Save, buffer.downgrade()) }) }); } } else if self.current_selection == 1 { if let Some(workspace) = self.workspace.upgrade() { + let (_, buffer, _) = workspace + .read(cx) + .active_item(cx)? + .act_as::(cx)? + .read(cx) + .active_excerpt(cx)?; + workspace.update(cx, |workspace, cx| { workspace.toggle_modal(window, cx, |window, cx| { - EncodingSelector::new(window, cx, Action::Reopen) + EncodingSelector::new(window, cx, Action::Reopen, buffer.downgrade()) }) }); } } + + Some(()) } } @@ -253,6 +270,7 @@ pub mod encoding { AppContext, BackgroundExecutor, DismissEvent, Entity, EventEmitter, Focusable, Length, WeakEntity, actions, }; + use language::Buffer; use picker::{Picker, PickerDelegate}; use ui::{ Context, DefiniteLength, HighlightedLabel, Label, ListItem, ListItemSpacing, ParentElement, @@ -261,6 +279,8 @@ pub mod encoding { use util::{ResultExt, TryFutureExt}; use workspace::{ModalView, Workspace}; + use crate::encoding_from_index; + pub struct EncodingSelector { picker: Entity>, action: Action, @@ -271,10 +291,14 @@ pub mod encoding { encodings: Vec, matches: Vec, selector: WeakEntity, + buffer: WeakEntity, } impl EncodingSelectorDelegate { - pub fn new(selector: WeakEntity) -> EncodingSelectorDelegate { + pub fn new( + selector: WeakEntity, + buffer: WeakEntity, + ) -> EncodingSelectorDelegate { EncodingSelectorDelegate { current_selection: 0, encodings: vec![ @@ -309,17 +333,17 @@ pub mod encoding { StringMatchCandidate::new(28, "Windows-1256"), StringMatchCandidate::new(29, "Windows-1257"), StringMatchCandidate::new(30, "Windows-1258"), - StringMatchCandidate::new(31, "EUC-KR"), + StringMatchCandidate::new(31, "Windows-949"), 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"), + StringMatchCandidate::new(33, "ISO 2022-JP"), + StringMatchCandidate::new(34, "GBK"), + StringMatchCandidate::new(35, "GB18030"), + StringMatchCandidate::new(36, "Big5"), + StringMatchCandidate::new(37, "HZ-GB-2312"), ], matches: Vec::new(), selector, + buffer, } } } @@ -403,6 +427,12 @@ pub mod encoding { window: &mut Window, cx: &mut Context>, ) { + if let Some(buffer) = self.buffer.upgrade() { + buffer.update(cx, |buffer, cx| { + buffer.encoding = encoding_from_index(self.current_selection) + }); + } + self.dismissed(window, cx); } fn dismissed(&mut self, window: &mut Window, cx: &mut Context>) { @@ -439,8 +469,9 @@ pub mod encoding { window: &mut Window, cx: &mut Context, action: Action, + buffer: WeakEntity, ) -> EncodingSelector { - let delegate = EncodingSelectorDelegate::new(cx.entity().downgrade()); + let delegate = EncodingSelectorDelegate::new(cx.entity().downgrade(), buffer); let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx)); EncodingSelector { picker, action }