mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
editor: Add base64 encode/decode commands (#55361)
Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Adds `editor: convert to base64` and `editor: convert from base64` to the command palette. Both commands operate on the current selection, or the word under the cursor when nothing is selected. The decode command silently no-ops on invalid base64 input or non-UTF-8 decoded bytes, consistent with how other convert commands handle untransformable input. Release Notes: - Added `editor: convert to base64` and `editor: convert from base64` commands to the command palette --------- Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
This commit is contained in:
parent
62507a1930
commit
8d22381695
6 changed files with 71 additions and 0 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -5467,6 +5467,7 @@ dependencies = [
|
|||
"aho-corasick",
|
||||
"anyhow",
|
||||
"assets",
|
||||
"base64 0.22.1",
|
||||
"breadcrumbs",
|
||||
"buffer_diff",
|
||||
"client",
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ test-support = [
|
|||
aho-corasick.workspace = true
|
||||
anyhow.workspace = true
|
||||
assets.workspace = true
|
||||
base64.workspace = true
|
||||
breadcrumbs.workspace = true
|
||||
client.workspace = true
|
||||
clock.workspace = true
|
||||
|
|
|
|||
|
|
@ -460,6 +460,10 @@ actions!(
|
|||
ConvertToRot13,
|
||||
/// Applies ROT47 cipher to selected text.
|
||||
ConvertToRot47,
|
||||
/// Base64-encodes the selected text or word under cursor.
|
||||
ConvertToBase64,
|
||||
/// Base64-decodes the selected text or word under cursor.
|
||||
ConvertFromBase64,
|
||||
/// Copies selected text to the clipboard.
|
||||
Copy,
|
||||
/// Copies selected text to the clipboard with leading/trailing whitespace trimmed.
|
||||
|
|
|
|||
|
|
@ -13362,6 +13362,35 @@ impl Editor {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn convert_to_base64(
|
||||
&mut self,
|
||||
_: &ConvertToBase64,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
use base64::Engine as _;
|
||||
self.manipulate_text(window, cx, |text| {
|
||||
base64::engine::general_purpose::STANDARD.encode(text)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn convert_from_base64(
|
||||
&mut self,
|
||||
_: &ConvertFromBase64,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
use base64::Engine as _;
|
||||
self.manipulate_text(
|
||||
window,
|
||||
cx,
|
||||
|text| match base64::engine::general_purpose::STANDARD.decode(text) {
|
||||
Ok(bytes) => String::from_utf8(bytes).unwrap_or_else(|_| text.to_string()),
|
||||
Err(_) => text.to_string(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn manipulate_text<Fn>(&mut self, window: &mut Window, cx: &mut Context<Self>, mut callback: Fn)
|
||||
where
|
||||
Fn: FnMut(&str) -> String,
|
||||
|
|
|
|||
|
|
@ -6864,6 +6864,40 @@ async fn test_convert_to_sentence_case(cx: &mut TestAppContext) {
|
|||
"});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_convert_to_base64(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
|
||||
// Encode a plain text selection
|
||||
cx.set_state(indoc! {"
|
||||
«helloˇ»
|
||||
"});
|
||||
cx.update_editor(|e, window, cx| e.convert_to_base64(&ConvertToBase64, window, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
«aGVsbG8=ˇ»
|
||||
"});
|
||||
|
||||
// Decode a valid base64 selection
|
||||
cx.set_state(indoc! {"
|
||||
«aGVsbG8=ˇ»
|
||||
"});
|
||||
cx.update_editor(|e, window, cx| e.convert_from_base64(&ConvertFromBase64, window, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
«helloˇ»
|
||||
"});
|
||||
|
||||
// Decode invalid base64 — should leave text unchanged
|
||||
cx.set_state(indoc! {"
|
||||
«not!!!ˇ»
|
||||
"});
|
||||
cx.update_editor(|e, window, cx| e.convert_from_base64(&ConvertFromBase64, window, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
«not!!!ˇ»
|
||||
"});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_manipulate_text(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
|
|
|||
|
|
@ -555,6 +555,8 @@ impl EditorElement {
|
|||
register_action(editor, window, Editor::toggle_case);
|
||||
register_action(editor, window, Editor::convert_to_rot13);
|
||||
register_action(editor, window, Editor::convert_to_rot47);
|
||||
register_action(editor, window, Editor::convert_to_base64);
|
||||
register_action(editor, window, Editor::convert_from_base64);
|
||||
register_action(editor, window, Editor::delete_to_previous_word_start);
|
||||
register_action(editor, window, Editor::delete_to_previous_subword_start);
|
||||
register_action(editor, window, Editor::delete_to_next_word_end);
|
||||
|
|
|
|||
Loading…
Reference in a new issue