summaryrefslogtreecommitdiff
path: root/examples/dte/bookmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/dte/bookmark.c')
-rw-r--r--examples/dte/bookmark.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/examples/dte/bookmark.c b/examples/dte/bookmark.c
new file mode 100644
index 0000000..174405f
--- /dev/null
+++ b/examples/dte/bookmark.c
@@ -0,0 +1,103 @@
+#include <stdlib.h>
+#include "bookmark.h"
+#include "buffer.h"
+#include "editor.h"
+#include "misc.h"
+#include "move.h"
+#include "search.h"
+#include "util/debug.h"
+#include "util/xmalloc.h"
+
+FileLocation *get_current_file_location(const View *view)
+{
+ const char *filename = view->buffer->abs_filename;
+ FileLocation *loc = xmalloc(sizeof(*loc));
+ *loc = (FileLocation) {
+ .filename = filename ? xstrdup(filename) : NULL,
+ .buffer_id = view->buffer->id,
+ .line = view->cy + 1,
+ .column = view->cx_char + 1
+ };
+ return loc;
+}
+
+bool file_location_go(Window *window, const FileLocation *loc)
+{
+ View *view = window_open_buffer(window, loc->filename, true, NULL);
+ if (!view) {
+ // Failed to open file; error message should be visible
+ return false;
+ }
+
+ if (window->view != view) {
+ set_view(view);
+ // Force centering view to cursor, because file changed
+ view->force_center = true;
+ }
+
+ if (loc->pattern) {
+ if (!search_tag(view, loc->pattern)) {
+ return false;
+ }
+ } else if (loc->line > 0) {
+ move_to_filepos(view, loc->line, loc->column ? loc->column : 1);
+ }
+
+ unselect(view);
+ return true;
+}
+
+static bool file_location_return(Window *window, const FileLocation *loc)
+{
+ Buffer *buffer = find_buffer_by_id(&window->editor->buffers, loc->buffer_id);
+ View *view;
+ if (buffer) {
+ view = window_get_view(window, buffer);
+ } else {
+ if (!loc->filename) {
+ // Can't restore closed buffer that had no filename; try again
+ return false;
+ }
+ view = window_open_buffer(window, loc->filename, true, NULL);
+ }
+
+ if (!view) {
+ // Open failed; don't try again
+ return true;
+ }
+
+ set_view(view);
+ unselect(view);
+ move_to_filepos(view, loc->line, loc->column);
+ return true;
+}
+
+void file_location_free(FileLocation *loc)
+{
+ free(loc->filename);
+ free(loc->pattern);
+ free(loc);
+}
+
+void bookmark_push(PointerArray *bookmarks, FileLocation *loc)
+{
+ const size_t max_entries = 256;
+ if (bookmarks->count == max_entries) {
+ file_location_free(ptr_array_remove_idx(bookmarks, 0));
+ }
+ BUG_ON(bookmarks->count >= max_entries);
+ ptr_array_append(bookmarks, loc);
+}
+
+void bookmark_pop(Window *window, PointerArray *bookmarks)
+{
+ void **ptrs = bookmarks->ptrs;
+ size_t count = bookmarks->count;
+ bool go = true;
+ while (count > 0 && go) {
+ FileLocation *loc = ptrs[--count];
+ go = !file_location_return(window, loc);
+ file_location_free(loc);
+ }
+ bookmarks->count = count;
+}