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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
/* Copyright 2007, 2008 Peter Klausler. See COPYING for license. */
#include "all.h"
void view_fold(struct view *view, position_t cursor, position_t mark)
{
size_t bytes = mark - cursor;
char buf[8];
if (mark < cursor)
bytes = -bytes, cursor = mark;
if (cursor > view->bytes)
return;
if (cursor + bytes > view->bytes)
bytes = view->bytes - cursor;
if (!bytes)
return;
view_insert(view, buf, cursor + bytes, unicode_utf8(buf, FOLD_END+bytes));
view_insert(view, buf, cursor, unicode_utf8(buf, FOLD_START+bytes));
view->text->foldings++;
}
sposition_t view_unfold(struct view *view, position_t offset)
{
position_t next, next2;
size_t fbytes;
Unicode_t ch = view_unicode(view, offset, &next);
if (ch < FOLD_START || ch >= FOLD_END)
return -1;
fbytes = FOLDED_BYTES(ch);
if (view_unicode(view, next + fbytes, &next2) !=
FOLD_END + fbytes)
return -1;
view_delete(view, next + fbytes, next2 - (next + fbytes));
view_delete(view, offset, next - offset);
view->text->foldings--;
return offset + fbytes;
}
void view_unfold_selection(struct view *view)
{
position_t offset = locus_get(view, CURSOR);
position_t end = locus_get(view, MARK);
if (end == UNSET)
return;
if (end < offset) {
position_t t = end;
end = offset;
offset = t;
}
while (offset < end) {
position_t next, next2;
size_t fbytes;
Unicode_t ch = view_unicode(view, offset, &next);
if (!IS_UNICODE(ch))
break;
if (ch < FOLD_START || ch >= FOLD_END) {
offset = next;
continue;
}
fbytes = FOLDED_BYTES(ch);
if (view_unicode(view, next + fbytes, &next2) !=
FOLD_END + fbytes) {
offset = next;
continue;
}
view_delete(view, next + fbytes, next2 - (next + fbytes));
view_delete(view, offset, next - offset);
view->text->foldings--;
offset += fbytes;
}
}
static int indentation(struct view *view, position_t offset)
{
unsigned indent = 0, tabstop = view->text->tabstop;
Unicode_t ch;
tabstop |= !tabstop;
for (;;)
if ((ch = view_char(view, offset, &offset)) == ' ')
indent++;
else if (ch == '\t')
indent = (indent / tabstop + 1) * tabstop;
else if (ch == '\n')
return -1;
else
break;
return indent;
}
static unsigned max_indentation(struct view *view)
{
position_t offset, next;
int maxindent = 0;
for (offset = 0; offset < view->bytes; offset = next) {
int indent = indentation(view, offset);
if (indent > maxindent)
maxindent = indent;
next = find_line_end(view, offset) + 1;
}
return maxindent;
}
void view_fold_indented(struct view *view, unsigned minindent)
{
unsigned maxindent;
minindent |= !minindent;
while ((maxindent = max_indentation(view)) >= minindent) {
position_t offset, next;
sposition_t start = -1;
for (offset = 0; offset < view->bytes; offset = next) {
next = find_line_end(view, offset) + 1;
if (indentation(view, offset) < maxindent) {
if (start >= 0) {
view_fold(view, next = start, offset-1);
start = -1;
}
} else if (start < 0)
start = offset - !!offset;
}
if (start >= 0)
view_fold(view, start, offset-1);
}
}
void view_unfold_all(struct view *view)
{
position_t offset, next;
if (!view->text->foldings)
return;
for (offset = 0;
IS_UNICODE(view_unicode(view, offset, &next));
offset = next)
if (view_unfold(view, offset) >= 0) {
if (!view->text->foldings)
break;
next = offset;
}
}
void text_unfold_all(struct text *text)
{
struct view *view;
if (!text->foldings)
return;
view_unfold_all(view = view_create(text));
view_close(view);
}
|