Compare commits
4 Commits
2f638c731a
...
44bf7c68ff
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44bf7c68ff | ||
|
|
4221aa8fb7 | ||
|
|
509db7af46 | ||
|
|
5c46844747 |
@@ -1,8 +1,8 @@
|
|||||||
- What precise workflow do I need for me to be viable to use this?
|
- What precise workflow do I need for me to be viable to use this?
|
||||||
- From a user (novice) point of view, how does it look like?
|
- From a user (novice) point of view, how does it look like?
|
||||||
|
|
||||||
|
- Open with seek string (open at pattern) filename:32 filename:/^Window$/
|
||||||
- build console window
|
- build console window
|
||||||
- Use WorkDir (raname to Workspace?) to shorten file names
|
|
||||||
- Show what process/coroutines are running and allow to kill (active process buffer?)
|
- Show what process/coroutines are running and allow to kill (active process buffer?)
|
||||||
- Database idea: use special buffers to store information
|
- Database idea: use special buffers to store information
|
||||||
- Editing the buffer doesn't seem to be the slow part rather, accessing the data and putting it into the buffer (potentially hitting many different memory locations) I have a crazy idea to use buffers in order to store the names in a serialized format
|
- Editing the buffer doesn't seem to be the slow part rather, accessing the data and putting it into the buffer (potentially hitting many different memory locations) I have a crazy idea to use buffers in order to store the names in a serialized format
|
||||||
@@ -19,10 +19,11 @@ Commands TODO:
|
|||||||
|
|
||||||
- CONSIDER AUTOMATING: CheckpointBeforeGoto
|
- CONSIDER AUTOMATING: CheckpointBeforeGoto
|
||||||
- GotoBackward how to handle that in case we want to automate and create on every move?
|
- GotoBackward how to handle that in case we want to automate and create on every move?
|
||||||
|
- Add jump checkpoints
|
||||||
|
- Make sure the timing window works forward and backward in undo and jump
|
||||||
|
|
||||||
|
|
||||||
backlog
|
backlog
|
||||||
ISSUE Ctrl+Alt+Down (DuplicateLine) doesn't work on ubuntu
|
|
||||||
FEATURE Search whole words, case sensitive etc.
|
FEATURE Search whole words, case sensitive etc.
|
||||||
FEATURE Select all searched occurences
|
FEATURE Select all searched occurences
|
||||||
FEATURE commands for scrolling: center, cursor_at_bottom_of_screen, cursor_at_top
|
FEATURE commands for scrolling: center, cursor_at_bottom_of_screen, cursor_at_top
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
typedef void OSErrorReport(const char *, ...);
|
||||||
|
|
||||||
#if OS_POSIX
|
#if OS_POSIX
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@@ -54,13 +56,19 @@ void RegisterCrashHandler(void) {
|
|||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
sa.sa_sigaction = CrashHandler;
|
sa.sa_sigaction = CrashHandler;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESETHAND; // Important flags!
|
||||||
|
|
||||||
sigaction(SIGSEGV, &sa, NULL);
|
|
||||||
sigaction(SIGABRT, &sa, NULL);
|
sigaction(SIGSEGV, &sa, NULL); // Segmentation fault
|
||||||
sigaction(SIGBUS, &sa, NULL);
|
sigaction(SIGABRT, &sa, NULL); // Abort
|
||||||
sigaction(SIGILL, &sa, NULL);
|
sigaction(SIGBUS, &sa, NULL); // Bus error
|
||||||
sigaction(SIGFPE, &sa, NULL);
|
sigaction(SIGILL, &sa, NULL); // Illegal instruction
|
||||||
|
sigaction(SIGFPE, &sa, NULL); // Floating point exception
|
||||||
|
sigaction(SIGTRAP, &sa, NULL); // Breakpoint/trap
|
||||||
|
sigaction(SIGSYS, &sa, NULL); // Bad system call
|
||||||
|
sigaction(SIGXCPU, &sa, NULL); // CPU time limit exceeded
|
||||||
|
sigaction(SIGXFSZ, &sa, NULL); // File size limit exceeded
|
||||||
|
sigaction(SIGTERM, &sa, NULL); // Termination request (optional)
|
||||||
}
|
}
|
||||||
|
|
||||||
API void InitOS(void (*error_proc)(const char *, ...)) {
|
API void InitOS(void (*error_proc)(const char *, ...)) {
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ API Int GetMin(Caret caret) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
API Int GetSize(Caret caret) {
|
||||||
|
return GetSize(caret.range);
|
||||||
|
}
|
||||||
|
|
||||||
API Caret MakeCaret(Int pos) {
|
API Caret MakeCaret(Int pos) {
|
||||||
Caret result = {};
|
Caret result = {};
|
||||||
result.range.min = result.range.max = pos;
|
result.range.min = result.range.max = pos;
|
||||||
@@ -874,12 +878,13 @@ API void AddEdit(Array<Edit> *e, Range range, String16 string) {
|
|||||||
// multicursor + history
|
// multicursor + history
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
void SaveHistoryBeforeMergeCursor(Buffer *buffer, Array<HistoryEntry> *stack, Array<Caret> &carets) {
|
HistoryEntry *SaveHistoryBeforeMergeCursor(Buffer *buffer, Array<HistoryEntry> *stack, Array<Caret> &carets) {
|
||||||
if (buffer->no_history) return;
|
if (buffer->no_history) return NULL;
|
||||||
HistoryEntry entry = {};
|
HistoryEntry entry = {};
|
||||||
entry.time = GetTimeSeconds();
|
entry.time = GetTimeSeconds();
|
||||||
entry.carets = TightCopy(GetSystemAllocator(), carets);
|
entry.carets = TightCopy(GetSystemAllocator(), carets);
|
||||||
Add(stack, entry);
|
Add(stack, entry);
|
||||||
|
return GetLast(*stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveHistoryBeforeApplyEdits(Buffer *buffer, Array<HistoryEntry> *stack, Array<Edit> &edits) {
|
void SaveHistoryBeforeApplyEdits(Buffer *buffer, Array<HistoryEntry> *stack, Array<Edit> &edits) {
|
||||||
@@ -924,7 +929,8 @@ API void RedoEdit(Buffer *buffer, Array<Caret> *carets) {
|
|||||||
|
|
||||||
HistoryEntry entry = Pop(&buffer->redo_stack);
|
HistoryEntry entry = Pop(&buffer->redo_stack);
|
||||||
|
|
||||||
SaveHistoryBeforeMergeCursor(buffer, &buffer->undo_stack, *carets);
|
HistoryEntry *e = SaveHistoryBeforeMergeCursor(buffer, &buffer->undo_stack, *carets);
|
||||||
|
e->time = entry.time;
|
||||||
SaveHistoryBeforeApplyEdits(buffer, &buffer->undo_stack, entry.edits);
|
SaveHistoryBeforeApplyEdits(buffer, &buffer->undo_stack, entry.edits);
|
||||||
ApplyEditsMultiCursor(buffer, entry.edits);
|
ApplyEditsMultiCursor(buffer, entry.edits);
|
||||||
|
|
||||||
@@ -934,6 +940,13 @@ API void RedoEdit(Buffer *buffer, Array<Caret> *carets) {
|
|||||||
Allocator sys_allocator = GetSystemAllocator();
|
Allocator sys_allocator = GetSystemAllocator();
|
||||||
For(entry.edits) Dealloc(sys_allocator, it.string.data);
|
For(entry.edits) Dealloc(sys_allocator, it.string.data);
|
||||||
Dealloc(&entry.edits);
|
Dealloc(&entry.edits);
|
||||||
|
|
||||||
|
if (buffer->redo_stack.len > 0) {
|
||||||
|
HistoryEntry *next = GetLast(buffer->redo_stack);
|
||||||
|
if (next->time - entry.time <= ConfigUndoMergeTimeWindow) {
|
||||||
|
RedoEdit(buffer, carets);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
API void UndoEdit(Buffer *buffer, Array<Caret> *carets) {
|
API void UndoEdit(Buffer *buffer, Array<Caret> *carets) {
|
||||||
@@ -942,8 +955,8 @@ API void UndoEdit(Buffer *buffer, Array<Caret> *carets) {
|
|||||||
if (buffer->undo_stack.len <= 0) return;
|
if (buffer->undo_stack.len <= 0) return;
|
||||||
|
|
||||||
HistoryEntry entry = Pop(&buffer->undo_stack);
|
HistoryEntry entry = Pop(&buffer->undo_stack);
|
||||||
|
HistoryEntry *e = SaveHistoryBeforeMergeCursor(buffer, &buffer->redo_stack, *carets);
|
||||||
SaveHistoryBeforeMergeCursor(buffer, &buffer->redo_stack, *carets);
|
e->time = entry.time;
|
||||||
SaveHistoryBeforeApplyEdits(buffer, &buffer->redo_stack, entry.edits);
|
SaveHistoryBeforeApplyEdits(buffer, &buffer->redo_stack, entry.edits);
|
||||||
ApplyEditsMultiCursor(buffer, entry.edits);
|
ApplyEditsMultiCursor(buffer, entry.edits);
|
||||||
|
|
||||||
@@ -956,7 +969,7 @@ API void UndoEdit(Buffer *buffer, Array<Caret> *carets) {
|
|||||||
|
|
||||||
if (buffer->undo_stack.len > 0) {
|
if (buffer->undo_stack.len > 0) {
|
||||||
HistoryEntry *next = GetLast(buffer->undo_stack);
|
HistoryEntry *next = GetLast(buffer->undo_stack);
|
||||||
if (entry.time - next->time <= ConfigUndoMergeTimeout) {
|
if (entry.time - next->time <= ConfigUndoMergeTimeWindow) {
|
||||||
UndoEdit(buffer, carets);
|
UndoEdit(buffer, carets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1505,8 +1518,8 @@ Buffer *BufferOpenFile(String path) {
|
|||||||
if (!FileExists(path)) {
|
if (!FileExists(path)) {
|
||||||
buffer = CreateBuffer(sys_allocator, path);
|
buffer = CreateBuffer(sys_allocator, path);
|
||||||
} else if (IsDir(path)) {
|
} else if (IsDir(path)) {
|
||||||
ReportWarningf("failed to open, it's a directory: %S", path);
|
buffer = CreateBuffer(sys_allocator, path);
|
||||||
return GetBuffer(NullBufferID);
|
buffer->is_dir = true;
|
||||||
} else {
|
} else {
|
||||||
String string = ReadFile(scratch, path);
|
String string = ReadFile(scratch, path);
|
||||||
buffer = CreateBuffer(sys_allocator, path, string.len * 4 + 4096);
|
buffer = CreateBuffer(sys_allocator, path, string.len * 4 + 4096);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ struct Buffer {
|
|||||||
unsigned dont_try_to_save_in_bulk_ops : 1;
|
unsigned dont_try_to_save_in_bulk_ops : 1;
|
||||||
unsigned close : 1;
|
unsigned close : 1;
|
||||||
unsigned special : 1;
|
unsigned special : 1;
|
||||||
|
unsigned is_dir : 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -19,27 +19,23 @@ BSet GetConsoleSet() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String GetCurrentFilename() {
|
|
||||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
|
||||||
return main.buffer->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
String GetDir(Buffer *buffer) {
|
String GetDir(Buffer *buffer) {
|
||||||
String name = ChopLastSlash(buffer->name);
|
if (buffer->is_dir) {
|
||||||
return name;
|
return buffer->name;
|
||||||
|
} else {
|
||||||
|
return ChopLastSlash(buffer->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String GetMainDir() {
|
String GetMainDir() {
|
||||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||||
String name = ChopLastSlash(main.buffer->name);
|
return GetDir(main.buffer);
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JumpGarbageBuffer(BSet *set, String buffer_name = "") {
|
void JumpGarbageBuffer(BSet *set, String buffer_name = "") {
|
||||||
CheckpointBeforeGoto(set->window);
|
CheckpointBeforeGoto(set->window);
|
||||||
if (buffer_name.len == 0) {
|
if (buffer_name.len == 0) {
|
||||||
String current_dir = ChopLastSlash(set->buffer->name);
|
buffer_name = GetUniqueBufferName(GetDir(set->buffer), "temp");
|
||||||
buffer_name = GetUniqueBufferName(current_dir, "temp");
|
|
||||||
}
|
}
|
||||||
set->view = WindowOpenBufferView(set->window, buffer_name);
|
set->view = WindowOpenBufferView(set->window, buffer_name);
|
||||||
set->buffer = GetBuffer(set->view->active_buffer);
|
set->buffer = GetBuffer(set->view->active_buffer);
|
||||||
@@ -618,10 +614,13 @@ BSet Open(Window *window, String path, String meta, bool set_active = true) {
|
|||||||
ActiveWindowID = set.window->id;
|
ActiveWindowID = set.window->id;
|
||||||
}
|
}
|
||||||
if (IsDir(o.path)) {
|
if (IsDir(o.path)) {
|
||||||
JumpGarbageBuffer(&set, GetUniqueBufferName(o.path, "temp", ".dirlisting"));
|
CheckpointBeforeGoto(set.window);
|
||||||
Appendf(set.view, "..\n");
|
View *view = WindowOpenBufferView(set.window, o.path);
|
||||||
|
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||||
|
ResetBuffer(buffer);
|
||||||
|
RawAppendf(buffer, "..\n");
|
||||||
for (FileIter it = IterateFiles(scratch, o.path); IsValid(it); Advance(&it)) {
|
for (FileIter it = IterateFiles(scratch, o.path); IsValid(it); Advance(&it)) {
|
||||||
Appendf(set.view, "%S\n", it.filename);
|
RawAppendf(buffer, "%S\n", it.filename);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CheckpointBeforeGoto(set.window);
|
CheckpointBeforeGoto(set.window);
|
||||||
@@ -852,14 +851,11 @@ void Command_GotoBackward() {
|
|||||||
void Command_GotoForward() {
|
void Command_GotoForward() {
|
||||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||||
GotoForward(main.window);
|
GotoForward(main.window);
|
||||||
} RegisterCommand(Command_GotoForward, "mousex2");
|
} RegisterCommand(Command_GotoForward, "alt-shift-q | mousex2");
|
||||||
|
|
||||||
void Command_OpenUpFolder() {
|
void Command_OpenUpFolder() {
|
||||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||||
String name = ChopLastSlash(main.buffer->name);
|
String name = ChopLastSlash(main.buffer->name);
|
||||||
if (EndsWith(main.buffer->name, "dirlisting")) {
|
|
||||||
name = ChopLastSlash(name);
|
|
||||||
}
|
|
||||||
Open(name);
|
Open(name);
|
||||||
} RegisterCommand(Command_OpenUpFolder, "ctrl-period");
|
} RegisterCommand(Command_OpenUpFolder, "ctrl-period");
|
||||||
|
|
||||||
|
|||||||
@@ -157,5 +157,7 @@ RegisterVariable(Int, ConfigFontSize, 15);
|
|||||||
RegisterVariable(Int, ConfigFontFilter, 0);
|
RegisterVariable(Int, ConfigFontFilter, 0);
|
||||||
RegisterVariable(String, ConfigFont, "/home/krz/text_editor/package/CascadiaMono.ttf");
|
RegisterVariable(String, ConfigFont, "/home/krz/text_editor/package/CascadiaMono.ttf");
|
||||||
RegisterVariable(String, ConfigVCVarsall, "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat");
|
RegisterVariable(String, ConfigVCVarsall, "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat");
|
||||||
RegisterVariable(Float, ConfigUndoMergeTimeout, 0.3);
|
RegisterVariable(Float, ConfigUndoMergeTimeWindow, 0.3);
|
||||||
|
RegisterVariable(Float, ConfigJumpHistoryMergeTimeWindow, 0.3);
|
||||||
|
RegisterVariable(Int, ConfigJumpHistorySize, 512);
|
||||||
RegisterVariable(String, ConfigInternetBrowser, "firefox");
|
RegisterVariable(String, ConfigInternetBrowser, "firefox");
|
||||||
|
|||||||
34
src/text_editor/scratch.cpp
Normal file
34
src/text_editor/scratch.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
|
||||||
|
void RunRingBufferTest() {
|
||||||
|
// Scratch scratch;
|
||||||
|
// RingBuffer<int> buff = {};
|
||||||
|
// Init(scratch, &buff, 4);
|
||||||
|
|
||||||
|
// for (int i = 0; i < 4; i += 1) {
|
||||||
|
// Add(&buff, i);
|
||||||
|
// }
|
||||||
|
// for (int i = 0; i < 4; i += 1) {
|
||||||
|
// Assert(buff.data[i] == i);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Add(&buff, 4);
|
||||||
|
// Assert(buff.data[0] == 4);
|
||||||
|
// Add(&buff, 5);
|
||||||
|
// Assert(buff.data[1] == 5);
|
||||||
|
// Assert(buff.data[2] == 2);
|
||||||
|
|
||||||
|
// Assert(Pop(&buff) == 5);
|
||||||
|
// Assert(Pop(&buff) == 4);
|
||||||
|
// Assert(Pop(&buff) == 3);
|
||||||
|
// Assert(Pop(&buff) == 2);
|
||||||
|
// Assert(Pop(&buff) == 0);
|
||||||
|
// Assert(Pop(&buff) == 0);
|
||||||
|
// Assert(Pop(&buff) == 0);
|
||||||
|
// Assert(Pop(&buff) == 0);
|
||||||
|
// Assert(Pop(&buff) == 0);
|
||||||
|
|
||||||
|
// // Assert(Pop(&buff) == 2);
|
||||||
|
|
||||||
|
|
||||||
|
} RegisterFunction(&TestFunctions, RunRingBufferTest);
|
||||||
@@ -39,10 +39,10 @@
|
|||||||
#include "commands.cpp"
|
#include "commands.cpp"
|
||||||
#include "commands_clipboard.cpp"
|
#include "commands_clipboard.cpp"
|
||||||
|
|
||||||
|
#include "scratch.cpp"
|
||||||
#include "draw.cpp"
|
#include "draw.cpp"
|
||||||
#include "test/tests.cpp"
|
#include "test/tests.cpp"
|
||||||
|
|
||||||
|
|
||||||
#if OS_WASM
|
#if OS_WASM
|
||||||
EM_JS(void, JS_SetMouseCursor, (const char *cursor_str), {
|
EM_JS(void, JS_SetMouseCursor, (const char *cursor_str), {
|
||||||
document.getElementById("canvas").style.cursor = UTF8ToString(cursor_str);
|
document.getElementById("canvas").style.cursor = UTF8ToString(cursor_str);
|
||||||
@@ -526,6 +526,12 @@ void Update(Event event) {
|
|||||||
{
|
{
|
||||||
ProfileScope(WindowEndOfFrameVisibilityAndLastActive);
|
ProfileScope(WindowEndOfFrameVisibilityAndLastActive);
|
||||||
For (Windows) {
|
For (Windows) {
|
||||||
|
if (it->goto_history.len > ConfigJumpHistorySize) {
|
||||||
|
RemoveByIndex(&it->goto_history, 0);
|
||||||
|
}
|
||||||
|
if (it->goto_redo.len > ConfigJumpHistorySize) {
|
||||||
|
RemoveByIndex(&it->goto_redo, 0);
|
||||||
|
}
|
||||||
if (it->sync_visibility_with_focus) {
|
if (it->sync_visibility_with_focus) {
|
||||||
if (it->id == ActiveWindowID) {
|
if (it->id == ActiveWindowID) {
|
||||||
it->visible = true;
|
it->visible = true;
|
||||||
@@ -642,6 +648,7 @@ extern char **environ;
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
InitOS((OSErrorReport *)printf);
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
int argc = __argc;
|
int argc = __argc;
|
||||||
char **argv = __argv;
|
char **argv = __argv;
|
||||||
|
|||||||
@@ -147,9 +147,6 @@ struct Register_Function {
|
|||||||
struct Register_Command { Register_Command(Array<CommandData> *fucs, Function *function, String name, String binding) { if (StartsWith(name, "Command_")) name = Skip(name, 8); Add(fucs, {name, binding, function}); } };
|
struct Register_Command { Register_Command(Array<CommandData> *fucs, Function *function, String name, String binding) { if (StartsWith(name, "Command_")) name = Skip(name, 8); Add(fucs, {name, binding, function}); } };
|
||||||
#define RegisterCommand(name, binding) Register_Command RC__##name(&CommandFunctions, name, #name, binding)
|
#define RegisterCommand(name, binding) Register_Command RC__##name(&CommandFunctions, name, #name, binding)
|
||||||
|
|
||||||
struct Register_Hook { Register_Hook(Array<PFunctionData> *functions, PFunction *function, String name) { if (StartsWith(name, "Hook_")) name = Skip(name, 5); Add(functions, {name, function}); } };
|
|
||||||
#define RegisterHook(functions, name) Register_Hook RC__##name(functions, (PFunction *)name, #name)
|
|
||||||
|
|
||||||
const int DIR_RIGHT = 0;
|
const int DIR_RIGHT = 0;
|
||||||
const int DIR_LEFT = 1;
|
const int DIR_LEFT = 1;
|
||||||
const int DIR_DOWN = 2;
|
const int DIR_DOWN = 2;
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ void CheckpointBeforeGoto(Window *window) {
|
|||||||
GotoCrumb GetCrumb(Array<GotoCrumb> *cr) {
|
GotoCrumb GetCrumb(Array<GotoCrumb> *cr) {
|
||||||
for (; cr->len;) {
|
for (; cr->len;) {
|
||||||
GotoCrumb c = Pop(cr);
|
GotoCrumb c = Pop(cr);
|
||||||
View *view = GetView(c.view_id);
|
View *view = FindView(c.view_id, NULL);
|
||||||
if (view) {
|
if (view) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -271,15 +271,15 @@ void GotoBackward(Window *window) {
|
|||||||
|
|
||||||
if (window->goto_history.len) {
|
if (window->goto_history.len) {
|
||||||
GotoCrumb *next = GetLast(window->goto_history);
|
GotoCrumb *next = GetLast(window->goto_history);
|
||||||
if (c.time - next->time <= ConfigUndoMergeTimeout) {
|
if (c.view_id == next->view_id && c.time - next->time <= ConfigJumpHistoryMergeTimeWindow) {
|
||||||
GotoBackward(window);
|
GotoBackward(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GotoForward(Window *window) {
|
void GotoForward(Window *window) {
|
||||||
if (window->goto_redo.len <= 0) return;
|
|
||||||
if (window->jump_history == false) return;
|
if (window->jump_history == false) return;
|
||||||
|
if (window->goto_redo.len <= 0) return;
|
||||||
BSet set = GetBSet(window);
|
BSet set = GetBSet(window);
|
||||||
Add(&window->goto_history, {set.view->id, set.view->carets[0], GetTimeSeconds()});
|
Add(&window->goto_history, {set.view->id, set.view->carets[0], GetTimeSeconds()});
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@ void GotoForward(Window *window) {
|
|||||||
|
|
||||||
if (window->goto_redo.len) {
|
if (window->goto_redo.len) {
|
||||||
GotoCrumb *next = GetLast(window->goto_redo);
|
GotoCrumb *next = GetLast(window->goto_redo);
|
||||||
if (c.time - next->time <= ConfigUndoMergeTimeout) {
|
if (c.view_id == next->view_id && next->time - c.time <= ConfigJumpHistoryMergeTimeWindow) {
|
||||||
GotoForward(window);
|
GotoForward(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ void Command_ShowBufferList() {
|
|||||||
ActiveWindowID = command_bar.window->id;
|
ActiveWindowID = command_bar.window->id;
|
||||||
ResetBuffer(command_bar.buffer);
|
ResetBuffer(command_bar.buffer);
|
||||||
For (Buffers) {
|
For (Buffers) {
|
||||||
if (it->special) {
|
if (it->special || it->garbage) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RawAppendf(command_bar.buffer, "\n%S", it->name);
|
RawAppendf(command_bar.buffer, "\n%S", it->name);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ void DebugWindowInit() {
|
|||||||
window->visible = false;
|
window->visible = false;
|
||||||
window->z = 2;
|
window->z = 2;
|
||||||
window->layout = false;
|
window->layout = false;
|
||||||
|
window->jump_history = false;
|
||||||
|
|
||||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(WorkDir, "debug"));
|
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(WorkDir, "debug"));
|
||||||
DebugBufferID = buffer->id;
|
DebugBufferID = buffer->id;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ void SearchWindowInit() {
|
|||||||
window->layout = false;
|
window->layout = false;
|
||||||
window->visible = false;
|
window->visible = false;
|
||||||
window->lose_visibility_on_escape = true;
|
window->lose_visibility_on_escape = true;
|
||||||
|
window->jump_history = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchWindowLayout(Rect2I *rect, Int wx, Int wy) {
|
void SearchWindowLayout(Rect2I *rect, Int wx, Int wy) {
|
||||||
@@ -33,10 +34,19 @@ void SearchWindowLayout(Rect2I *rect, Int wx, Int wy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Command_Search() {
|
void Command_Search() {
|
||||||
|
BSet main = GetBSet(ActiveWindowID);
|
||||||
|
String16 string = {};
|
||||||
|
if (main.view->carets.len == 1 && GetSize(main.view->carets[0]) > 0) {
|
||||||
|
string = GetString(main.buffer, main.view->carets[0].range);
|
||||||
|
}
|
||||||
BSet set = GetBSet(SearchWindowID);
|
BSet set = GetBSet(SearchWindowID);
|
||||||
set.window->visible = true;
|
set.window->visible = true;
|
||||||
ActiveWindowID = SearchWindowID;
|
ActiveWindowID = SearchWindowID;
|
||||||
SelectEntireBuffer(set.view);
|
SelectEntireBuffer(set.view);
|
||||||
|
if (string.len > 0) {
|
||||||
|
Replace(set.view, string);
|
||||||
|
SelectEntireBuffer(set.view);
|
||||||
|
}
|
||||||
} RegisterCommand(Command_Search, "ctrl-f");
|
} RegisterCommand(Command_Search, "ctrl-f");
|
||||||
|
|
||||||
void SearchWindowFindNext(bool forward = true) {
|
void SearchWindowFindNext(bool forward = true) {
|
||||||
|
|||||||
Reference in New Issue
Block a user