Make the status bar encoding indicator update the encoding when an encoding from the selector is chosen.

This commit is contained in:
R Aadarsh 2025-08-24 20:34:33 +05:30
parent 5fec768e37
commit 43357f689c
4 changed files with 144 additions and 13 deletions

1
Cargo.lock generated
View file

@ -5275,6 +5275,7 @@ dependencies = [
"encoding",
"fuzzy",
"gpui",
"language",
"picker",
"ui",
"util",

View file

@ -13,6 +13,7 @@ util.workspace = true
fuzzy.workspace = true
editor.workspace = true
encoding = "0.2.33"
language.workspace = true
[lints]
workspace = true

View file

@ -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,
}
}

View file

@ -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<Picker<EncodingSaveOrReopenDelegate>>,
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::<Editor>(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::<Editor>(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<Picker<EncodingSelectorDelegate>>,
action: Action,
@ -271,10 +291,14 @@ pub mod encoding {
encodings: Vec<StringMatchCandidate>,
matches: Vec<StringMatch>,
selector: WeakEntity<EncodingSelector>,
buffer: WeakEntity<Buffer>,
}
impl EncodingSelectorDelegate {
pub fn new(selector: WeakEntity<EncodingSelector>) -> EncodingSelectorDelegate {
pub fn new(
selector: WeakEntity<EncodingSelector>,
buffer: WeakEntity<Buffer>,
) -> 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<Picker<Self>>,
) {
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<Picker<Self>>) {
@ -439,8 +469,9 @@ pub mod encoding {
window: &mut Window,
cx: &mut Context<EncodingSelector>,
action: Action,
buffer: WeakEntity<Buffer>,
) -> 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 }