Clipboard

This commit is contained in:
Krzosa Karol
2024-07-22 08:15:40 +02:00
parent a5069cd148
commit 254407e89e
5 changed files with 103 additions and 7 deletions

View File

@@ -104,7 +104,7 @@ void AfterEdit(Buffer *buffer, Array<Edit> *edits, Array<Caret> *carets) {
buffer->debug_edit_phase -= 2; buffer->debug_edit_phase -= 2;
HistoryEntry *entry = GetLast(buffer->undo_stack); HistoryEntry *entry = GetLast(buffer->undo_stack);
#if 1 #if BUFFER_DEBUG
Assert(entry->carets.len); Assert(entry->carets.len);
Assert(entry->edits.len); Assert(entry->edits.len);
for (Int i = 0; i < edits->len - 1; i += 1) { for (Int i = 0; i < edits->len - 1; i += 1) {
@@ -133,8 +133,4 @@ void AfterEdit(Buffer *buffer, Array<Edit> *edits, Array<Caret> *carets) {
} }
} }
for (Int i = 0; i < carets->len; i += 1) carets->data[i] = new_carets[i]; for (Int i = 0; i < carets->len; i += 1) carets->data[i] = new_carets[i];
// Make sure all carets are in range
// @todo: remove?
For(*carets) it.range = Clamp(*buffer, it.range);
} }

View File

@@ -49,3 +49,28 @@ bool AreEqual(String16 a, String16 b, unsigned ignore_case = false) {
} }
inline bool operator==(String16 a, String16 b) { return AreEqual(a, b); } inline bool operator==(String16 a, String16 b) { return AreEqual(a, b); }
inline bool operator!=(String16 a, String16 b) { return !AreEqual(a, b); } inline bool operator!=(String16 a, String16 b) { return !AreEqual(a, b); }
String16 Merge(Allocator allocator, Array<String16> list, String16 separator = " ") {
int64_t char_count = 0;
For(list) char_count += it.len;
if (char_count == 0) return {};
int64_t node_count = list.len;
int64_t base_size = (char_count + 1);
int64_t sep_size = (node_count - 1) * separator.len;
int64_t size = base_size + sep_size;
wchar_t *buff = (wchar_t *)AllocSize(allocator, sizeof(wchar_t) * (size + 1));
String16 string = {buff, 0};
For(list) {
Assert(string.len + it.len <= size);
memcpy(string.data + string.len, it.data, it.len * sizeof(wchar_t));
string.len += it.len;
if (!IsLast(list, it)) {
memcpy(string.data + string.len, separator.data, separator.len * sizeof(wchar_t));
string.len += separator.len;
}
}
Assert(string.len == size - 1);
string.data[size] = 0;
return string;
}

View File

@@ -22,13 +22,12 @@
#include "colors.cpp" #include "colors.cpp"
#include "view.h" #include "view.h"
#include "view_commands_clipboard.cpp"
#include "view_commands.cpp" #include "view_commands.cpp"
#include "view_draw.cpp" #include "view_draw.cpp"
/* /*
- Ctrl + Z, Ctrl + C - Undo redo history
- Ctrl + D - create new cursor at next occurence of word - Ctrl + D - create new cursor at next occurence of word
- Ctrl + X, Ctrl + C, Ctrl + V - Copy paste
- Scrollbars - Scrollbars
- Line numbers - Line numbers
- file info bar at bottom (line, column, line endings) - file info bar at bottom (line, column, line endings)

View File

@@ -222,6 +222,15 @@ void HandleKeybindings(View *_view) {
UndoEdit(&buf, &view.carets); UndoEdit(&buf, &view.carets);
} }
if (CtrlPress(KEY_C)) {
Command_Copy(&view);
} else if (CtrlPress(KEY_V)) {
Command_Paste(&view);
} else if (CtrlPress(KEY_X)) {
Command_Copy(&view);
Command_Replace(&view, L"");
}
if (ShiftPress(KEY_PAGE_UP)) { if (ShiftPress(KEY_PAGE_UP)) {
Command_MoveCursorsByPageSize(&view, DIR_UP, SHIFT_PRESSED); Command_MoveCursorsByPageSize(&view, DIR_UP, SHIFT_PRESSED);
} else if (Press(KEY_PAGE_UP)) { } else if (Press(KEY_PAGE_UP)) {

View File

@@ -0,0 +1,67 @@
String16 SavedClipboardString;
Array<String16> SavedClipboardCursors;
void Command_Copy(View *view) {
Allocator sys_allocator = GetSystemAllocator();
SavedClipboardCursors.allocator = sys_allocator;
if (SavedClipboardCursors.data) {
For(SavedClipboardCursors) Dealloc(sys_allocator, &it.data);
SavedClipboardCursors.len = 0;
}
if (SavedClipboardString.data) {
Dealloc(sys_allocator, &SavedClipboardString.data);
SavedClipboardString = {};
}
// First, if there is no selection - select the entire line
For(view->carets) {
if (GetSize(it.range) == 0) {
Int line = PosToLine(*view->buffer, it.range.min);
Range line_range = GetLineRange(*view->buffer, line);
it.range = line_range;
}
}
For(view->carets) {
String16 string = GetString(*view->buffer, it.range);
String16 copy = Copy(sys_allocator, string);
Add(&SavedClipboardCursors, copy);
}
// @todo: maybe only add new line if there is no new line at the end, experiment with it
SavedClipboardString = Merge(sys_allocator, SavedClipboardCursors, L"\n");
Scratch scratch;
SetClipboardText(ToString(scratch, SavedClipboardString).data);
}
void Command_Paste(View *view) {
Scratch scratch;
const char *text = GetClipboardText();
String string_ = text;
String16 string = ToString16(scratch, string_);
// Regular paste
if (string != SavedClipboardString || SavedClipboardCursors.len != view->carets.len) {
BeforeEdit(view->buffer, view->carets);
MergeCarets(&view->carets);
Array<Edit> edits = {scratch};
For(view->carets) AddEdit(&edits, it.range, string);
ApplyEdits(view->buffer, edits);
AfterEdit(view->buffer, &edits, &view->carets);
return;
}
// Multicursor paste
BeforeEdit(view->buffer, view->carets);
MergeCarets(&view->carets);
Array<Edit> edits = {scratch};
for (int64_t i = 0; i < view->carets.len; i += 1) {
String16 string = SavedClipboardCursors[i];
Caret &it = view->carets[i];
AddEdit(&edits, it.range, string);
}
ApplyEdits(view->buffer, edits);
AfterEdit(view->buffer, &edits, &view->carets);
}