@@ -74,7 +74,7 @@ use gpui::{
div, impl_actions, point, prelude::*, px, relative, size, uniform_list, Action, AnyElement,
AppContext, AsyncWindowContext, AvailableSpace, BackgroundExecutor, Bounds, ClipboardEntry,
ClipboardItem, Context, DispatchPhase, ElementId, EventEmitter, FocusHandle, FocusOutEvent,
- FocusableView, FontId, FontWeight, HighlightStyle, Hsla, InteractiveText, KeyContext,
+ FocusableView, FontId, FontWeight, Global, HighlightStyle, Hsla, InteractiveText, KeyContext,
ListSizingBehavior, Model, ModelContext, MouseButton, PaintQuad, ParentElement, Pixels, Render,
ScrollStrategy, SharedString, Size, StrikethroughStyle, Styled, StyledText, Subscription, Task,
TextStyle, TextStyleRefinement, UTF16Selection, UnderlineStyle, UniformListScrollHandle, View,
@@ -7364,7 +7364,7 @@ impl Editor {
.update(cx, |buffer, cx| buffer.edit(edits, None, cx));
}
- pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext<Self>) {
+ pub fn cut_common(&mut self, cx: &mut ViewContext<Self>) -> ClipboardItem {
let mut text = String::new();
let buffer = self.buffer.read(cx).snapshot(cx);
let mut selections = self.selections.all::<Point>(cx);
@@ -7408,11 +7408,38 @@ impl Editor {
s.select(selections);
});
this.insert("", cx);
- cx.write_to_clipboard(ClipboardItem::new_string_with_json_metadata(
- text,
- clipboard_selections,
- ));
});
+ ClipboardItem::new_string_with_json_metadata(text, clipboard_selections)
+ }
+
+ pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext<Self>) {
+ let item = self.cut_common(cx);
+ cx.write_to_clipboard(item);
+ }
+
+ pub fn kill_ring_cut(&mut self, _: &KillRingCut, cx: &mut ViewContext<Self>) {
+ self.change_selections(None, cx, |s| {
+ s.move_with(|snapshot, sel| {
+ if sel.is_empty() {
+ sel.end = DisplayPoint::new(sel.end.row(), snapshot.line_len(sel.end.row()))
+ }
+ });
+ });
+ let item = self.cut_common(cx);
+ cx.set_global(KillRing(item))
+ }
+
+ pub fn kill_ring_yank(&mut self, _: &KillRingYank, cx: &mut ViewContext<Self>) {
+ let (text, metadata) = if let Some(KillRing(item)) = cx.try_global() {
+ if let Some(ClipboardEntry::String(kill_ring)) = item.entries().first() {
+ (kill_ring.text().to_string(), kill_ring.metadata_json())
+ } else {
+ return;
+ }
+ } else {
+ return;
+ };
+ self.do_paste(&text, metadata, false, cx);
}
pub fn copy(&mut self, _: &Copy, cx: &mut ViewContext<Self>) {
@@ -15145,4 +15172,7 @@ fn check_multiline_range(buffer: &Buffer, range: Range<usize>) -> Range<usize> {
}
}
+pub struct KillRing(ClipboardItem);
+impl Global for KillRing {}
+
const UPDATE_DEBOUNCE: Duration = Duration::from_millis(50);
@@ -217,6 +217,8 @@ impl EditorElement {
register_action(view, cx, Editor::transpose);
register_action(view, cx, Editor::rewrap);
register_action(view, cx, Editor::cut);
+ register_action(view, cx, Editor::kill_ring_cut);
+ register_action(view, cx, Editor::kill_ring_yank);
register_action(view, cx, Editor::copy);
register_action(view, cx, Editor::paste);
register_action(view, cx, Editor::undo);