1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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;
}
|