@@ -19253,6 +19253,212 @@ fn test_highlighted_ranges(cx: &mut TestAppContext) {
});
}
+#[gpui::test]
+async fn test_copy_highlight_json(cx: &mut TestAppContext) {
+ init_test(cx, |_| {});
+
+ let mut cx = EditorTestContext::new(cx).await;
+ cx.set_state(indoc! {"
+ fn main() {
+ let x = 1;ˇ
+ }
+ "});
+ setup_rust_syntax_highlighting(&mut cx);
+
+ cx.update_editor(|editor, window, cx| {
+ editor.copy_highlight_json(&CopyHighlightJson, window, cx);
+ });
+
+ let clipboard_json: serde_json::Value =
+ serde_json::from_str(&cx.read_from_clipboard().unwrap().text().unwrap()).unwrap();
+ assert_eq!(
+ clipboard_json,
+ json!([
+ [
+ {"text": "fn", "highlight": "keyword"},
+ {"text": " ", "highlight": null},
+ {"text": "main", "highlight": "function"},
+ {"text": "()", "highlight": "punctuation.bracket"},
+ {"text": " ", "highlight": null},
+ {"text": "{", "highlight": "punctuation.bracket"},
+ ],
+ [
+ {"text": " ", "highlight": null},
+ {"text": "let", "highlight": "keyword"},
+ {"text": " ", "highlight": null},
+ {"text": "x", "highlight": "variable"},
+ {"text": " ", "highlight": null},
+ {"text": "=", "highlight": "operator"},
+ {"text": " ", "highlight": null},
+ {"text": "1", "highlight": "number"},
+ {"text": ";", "highlight": "punctuation.delimiter"},
+ ],
+ [
+ {"text": "}", "highlight": "punctuation.bracket"},
+ ],
+ ])
+ );
+}
+
+#[gpui::test]
+async fn test_copy_highlight_json_selected_range(cx: &mut TestAppContext) {
+ init_test(cx, |_| {});
+
+ let mut cx = EditorTestContext::new(cx).await;
+ cx.set_state(indoc! {"
+ fn main() {
+ «let x = 1;
+ let yˇ» = 2;
+ }
+ "});
+ setup_rust_syntax_highlighting(&mut cx);
+
+ cx.update_editor(|editor, window, cx| {
+ editor.copy_highlight_json(&CopyHighlightJson, window, cx);
+ });
+
+ let clipboard_json: serde_json::Value =
+ serde_json::from_str(&cx.read_from_clipboard().unwrap().text().unwrap()).unwrap();
+ assert_eq!(
+ clipboard_json,
+ json!([
+ [
+ {"text": "let", "highlight": "keyword"},
+ {"text": " ", "highlight": null},
+ {"text": "x", "highlight": "variable"},
+ {"text": " ", "highlight": null},
+ {"text": "=", "highlight": "operator"},
+ {"text": " ", "highlight": null},
+ {"text": "1", "highlight": "number"},
+ {"text": ";", "highlight": "punctuation.delimiter"},
+ ],
+ [
+ {"text": " ", "highlight": null},
+ {"text": "let", "highlight": "keyword"},
+ {"text": " ", "highlight": null},
+ {"text": "y", "highlight": "variable"},
+ ],
+ ])
+ );
+}
+
+#[gpui::test]
+async fn test_copy_highlight_json_selected_line_range(cx: &mut TestAppContext) {
+ init_test(cx, |_| {});
+
+ let mut cx = EditorTestContext::new(cx).await;
+
+ cx.set_state(indoc! {"
+ fn main() {
+ «let x = 1;
+ let yˇ» = 2;
+ }
+ "});
+ setup_rust_syntax_highlighting(&mut cx);
+
+ cx.update_editor(|editor, window, cx| {
+ editor.selections.set_line_mode(true);
+ editor.copy_highlight_json(&CopyHighlightJson, window, cx);
+ });
+
+ let clipboard_json: serde_json::Value =
+ serde_json::from_str(&cx.read_from_clipboard().unwrap().text().unwrap()).unwrap();
+ assert_eq!(
+ clipboard_json,
+ json!([
+ [
+ {"text": " ", "highlight": null},
+ {"text": "let", "highlight": "keyword"},
+ {"text": " ", "highlight": null},
+ {"text": "x", "highlight": "variable"},
+ {"text": " ", "highlight": null},
+ {"text": "=", "highlight": "operator"},
+ {"text": " ", "highlight": null},
+ {"text": "1", "highlight": "number"},
+ {"text": ";", "highlight": "punctuation.delimiter"},
+ ],
+ [
+ {"text": " ", "highlight": null},
+ {"text": "let", "highlight": "keyword"},
+ {"text": " ", "highlight": null},
+ {"text": "y", "highlight": "variable"},
+ {"text": " ", "highlight": null},
+ {"text": "=", "highlight": "operator"},
+ {"text": " ", "highlight": null},
+ {"text": "2", "highlight": "number"},
+ {"text": ";", "highlight": "punctuation.delimiter"},
+ ],
+ ])
+ );
+}
+
+#[gpui::test]
+async fn test_copy_highlight_json_single_line(cx: &mut TestAppContext) {
+ init_test(cx, |_| {});
+
+ let mut cx = EditorTestContext::new(cx).await;
+
+ cx.set_state(indoc! {"
+ fn main() {
+ let ˇx = 1;
+ let y = 2;
+ }
+ "});
+ setup_rust_syntax_highlighting(&mut cx);
+
+ cx.update_editor(|editor, window, cx| {
+ editor.selections.set_line_mode(true);
+ editor.copy_highlight_json(&CopyHighlightJson, window, cx);
+ });
+
+ let clipboard_json: serde_json::Value =
+ serde_json::from_str(&cx.read_from_clipboard().unwrap().text().unwrap()).unwrap();
+ assert_eq!(
+ clipboard_json,
+ json!([
+ [
+ {"text": " ", "highlight": null},
+ {"text": "let", "highlight": "keyword"},
+ {"text": " ", "highlight": null},
+ {"text": "x", "highlight": "variable"},
+ {"text": " ", "highlight": null},
+ {"text": "=", "highlight": "operator"},
+ {"text": " ", "highlight": null},
+ {"text": "1", "highlight": "number"},
+ {"text": ";", "highlight": "punctuation.delimiter"},
+ ]
+ ])
+ );
+}
+
+fn setup_rust_syntax_highlighting(cx: &mut EditorTestContext) {
+ let syntax = SyntaxTheme::new_test(vec![
+ ("keyword", Hsla::red()),
+ ("function", Hsla::blue()),
+ ("variable", Hsla::green()),
+ ("number", Hsla::default()),
+ ("operator", Hsla::default()),
+ ("punctuation.bracket", Hsla::default()),
+ ("punctuation.delimiter", Hsla::default()),
+ ]);
+
+ let language = rust_lang();
+ language.set_theme(&syntax);
+
+ cx.update_buffer(|buffer, cx| buffer.set_language(Some(language), cx));
+ cx.executor().run_until_parked();
+ cx.update_editor(|editor, window, cx| {
+ editor.set_style(
+ EditorStyle {
+ syntax: Arc::new(syntax),
+ ..Default::default()
+ },
+ window,
+ cx,
+ );
+ });
+}
+
#[gpui::test]
async fn test_following(cx: &mut TestAppContext) {
init_test(cx, |_| {});