From fffa58a286e628270cfc3eed57f62ff1bb834544 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 18 Oct 2025 09:56:45 +1100 Subject: [PATCH] buffer fixes, indenting fix --- src/editor/buffer.d | 370 +++++++++++++++++++++++-------------------- src/editor/editor.d | 10 +- src/editor/parsing.d | 65 ++++---- src/editor/ui.d | 15 +- 4 files changed, 252 insertions(+), 208 deletions(-) diff --git a/src/editor/buffer.d b/src/editor/buffer.d index bb61d47..cedabe2 100644 --- a/src/editor/buffer.d +++ b/src/editor/buffer.d @@ -1,6 +1,7 @@ import dlib; import core.stdc.stdio : EOF; import parsing; +import parsing : SetBuffers; import std.format : sformat; import std.math.algebraic : abs; import editor; @@ -10,14 +11,18 @@ struct FlatBuffer Tokenizer tk; Arena arena; Arena ls_arena; - u8[] file_name; - u8[] data; - LineStart[] line_starts; - u64 length; - u64 lf_count; - i64 buf_pos; - i64 offset; + u8[] file_name; + + u8[] _buf; + u8* pbuf; + u64 length; + + LineStart[] lines; + u64 line_count; + + i64 pos; + i64 line_offset; i64 rows; I64Vec2 sel; @@ -38,6 +43,8 @@ alias SM = SelectMode; struct LineStart { u64 pos; + u64 length; + u32 line; u16 level; } @@ -100,51 +107,62 @@ const bool[128] SYM_TOKENS = [ ';': true, ]; +const u64 SPACING = 2; +const u64 BUF_START = 1; + FlatBuffer -CreateFlatBuffer(u8[] data) +CreateFlatBuffer(u8[] data, u8[] file_name) { - u64 capacity = data.length > 0 ? RoundUp(cast(u64)(data.length) * 2, KB(4)) : KB(4); - - u8[] buf = Alloc!(u8)(capacity); - buf[0 .. data.length] = data[0 .. data.length]; - FlatBuffer fb = { arena: CreateArena(MB(1)), ls_arena: CreateArena(KB(512)), - data: buf, - length: cast(u64)data.length, - lf_count: CountLF(data), - sel: -1, }; + Init(&fb, data, file_name); fb.tk = CreateTokenizer(&fb); - Fix(&fb); return fb; } void -Change(FlatBuffer* fb, u8[] data) +Init(FlatBuffer* fb, u8[] data, u8[] file_name) { - Free(fb.data); + u64 capacity = data.length > 0 ? RoundUp(cast(u64)(data.length)*2, KB(4)) : KB(4); - u64 cap = data.length > 0 ? RoundUp(cast(u64)(data.length) * 2, KB(4)) : KB(4); + u8[] buf = Alloc!(u8)(capacity); - fb.data = Alloc!(u8)(cap); - fb.data[0 .. data.length] = data[0 .. $]; - fb.length = data.length; - fb.lf_count = CountLF(data); + fb.file_name = file_name; + fb.line_count = CountLF(data); + fb.sel = -1; + fb.sel_mode = SM.None; - ResetTokenizer(fb); + SetBuffers(fb, buf); + MemCpy(fb.pbuf, data.ptr, data.length); +} + +void +SetBuffers(FlatBuffer* fb, u8[] data) +{ + fb._buf = data; + fb.pbuf = fb._buf.ptr+BUF_START; +} + +void +Change(FlatBuffer* fb, u8[] data, u8[] file_name) +{ + Free(fb._buf); + + Init(fb, data, file_name); + ResetTokenizer(&fb.tk, fb._buf.length); Fix(fb); } u64 CountLF(u8[] data) { - u64 lf_count = 0; + u64 lf_count = 1; for(u64 i = 0; i < data.length; i += 1) { lf_count += u64(data.ptr[i] == '\n'); @@ -153,20 +171,42 @@ CountLF(u8[] data) return lf_count; } +pragma(inline) bool +ScanLineRightBrace(u8* pbuf, u64 start, u64 len) +{ + bool result; + for(u64 i = start; i < len; i += 1) + { + if(pbuf[i] == '\t' || pbuf[i] == ' ') continue; + + if(pbuf[i] == '}' || pbuf[i] == ']' || pbuf[i] == ')') + { + result = true; + break; + } + + break; + } + + return result; +} + void Fix(FlatBuffer* fb) { with(fb) { Reset(&ls_arena); - line_starts = Alloc!(LineStart)(&ls_arena, lf_count+1); - line_starts[0].pos = 0; + + lines = Alloc!(LineStart)(&ls_arena, line_count); + lines[0].pos = 0; - u16 ignore, pending_level, level; - u64 ls_idx = 1; + LineStart* prev = null; + u16 ignore, pending_level, level; + u64 ls_idx = 1; for(u64 i = 0; i < length; i += 1) { - if(data[i] == '{' || data[i] == '(' || data[i] == '[') + if(pbuf[i] == '{' || pbuf[i] == '(' || pbuf[i] == '[') { if(pending_level > 0) { @@ -178,7 +218,7 @@ Fix(FlatBuffer* fb) } } - if(data[i] == '}' || data[i] == ')' || data[i] == ']') + else if(pbuf[i] == '}' || pbuf[i] == ')' || pbuf[i] == ']') { if(ignore > 0) { @@ -190,22 +230,35 @@ Fix(FlatBuffer* fb) } else if(level > 0) { + if(prev) + { + prev.level = cast(u16)Max(prev.level-u16(1), 0); + } level -= 1; } } - if(data[i] == '\n') + if(pbuf[i] == '\n') { level += pending_level; pending_level = 0; - line_starts[ls_idx].pos = i+1; - line_starts[ls_idx].level = level; + lines[ls_idx].pos = i+1; + lines[ls_idx].level = level; + + prev = &lines[ls_idx]; ls_idx += 1; } } + for(u64 i = 0; i < line_count-1; i += 1) + { + lines[i].length = lines[i+1].pos - lines[i+0].pos; + } + + lines[line_count-1].length = length - lines[line_count-1].pos; + dirty = false; TokenizeD(fb); @@ -215,25 +268,23 @@ Fix(FlatBuffer* fb) LineBuffers CreateLineBuffers(u64 arena_size) { - return LineBuffers( - arena: CreateArena(arena_size), - ); + return LineBuffers(arena: CreateArena(arena_size)); } void Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos) { - if(fb.length + length > fb.data.length) + if(fb.length + length > fb._buf.length-SPACING) { - fb.tk.buffer = Realloc!(TokenStyle)(fb.tk.buffer, fb.data.length*2); - fb.data = Realloc!(u8)(fb.data, fb.data.length*2); + SetBuffers(&fb.tk, Realloc(fb.tk._tokens, fb._buf.length*2)); + SetBuffers(fb, Realloc(fb._buf, fb._buf.length*2)); } - u64 prev_lf = fb.lf_count; + u64 new_lines; for(u64 i = 0; i < length; i += 1) { - fb.buf_pos += 1; - fb.lf_count += u64(insert.ptr[i] == '\n'); + fb.pos += 1; + new_lines += u64(insert.ptr[i] == '\n'); } if(length == 1) @@ -250,14 +301,13 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos) if(new_ch == '\n' && pos > 0) { - Logf("yeah"); - u8 l = fb.data[pos-1]; - u8 r = fb.data[pos]; + u8 l = fb.pbuf[pos-1]; + u8 r = fb.pbuf[pos]; bool expand = (l == '(' && r == ')') || (l == '{' && r == '}') || (l == '[' && r == ']'); u32 level = LevelFromPos(fb, pos) + u32(expand); u64 limit = level + length; - for(; length < limit; length += 1, fb.buf_pos += 1) + for(; length < limit; length += 1, fb.pos += 1) { insert[length] = '\t'; } @@ -265,7 +315,7 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos) if(expand) { insert[length++] = '\n'; - fb.lf_count += 1; + new_lines += 1; limit = level-1+length; for(; length < limit; length += 1) @@ -276,21 +326,23 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos) } else if(new_ch != '\n' && new_ch > 0) { - length += 1; + length += 1; insert[1] = new_ch; } } u64 temp_len = fb.length-pos; - u8[] temp = Alloc!(u8)(&fb.arena, fb.data, pos, temp_len); + u8[] temp = Alloc!(u8)(&fb.arena, fb.pbuf[pos .. pos+temp_len]); - fb.data[pos .. pos+length] = insert[0 .. length]; + fb.pbuf[pos .. pos+length] = insert[0 .. length]; pos += length; - fb.data[pos .. pos+temp_len] = temp[0 .. temp_len]; + fb.pbuf[pos .. pos+temp_len] = temp[0 .. temp_len]; fb.length += length; + fb.line_count += new_lines; + Fix(fb); Reset(&fb.arena); @@ -318,7 +370,7 @@ StartSelection(FlatBuffer* fb, SelectMode mode) if(mode == SM.Normal) { - fb.sel = fb.buf_pos; + fb.sel = fb.pos; } else if(mode == SM.Line) { @@ -336,26 +388,26 @@ EndSelection(FlatBuffer* fb) void Insert(FlatBuffer* fb, u8[] insert, u64 length) { - Insert(fb, insert, length, fb.buf_pos); + Insert(fb, insert, length, fb.pos); } pragma(inline) u64 CurrentLine(FlatBuffer* fb) { - return LineFromPos(fb, fb.buf_pos); + return LineFromPos(fb, fb.pos); } pragma(inline) u64 CurrentCol(FlatBuffer* fb) { - return LinePos(fb, fb.buf_pos); + return LinePos(fb, fb.pos); } pragma(inline) u64 LinePos(FlatBuffer* fb, u64 pos) { u64 line = LineFromPos(fb, pos); - return pos - fb.line_starts[line].pos; + return pos - fb.lines[line].pos; } pragma(inline) U64Vec2 @@ -368,9 +420,9 @@ pragma(inline) u64 LineFromPos(FlatBuffer* fb, u64 pos) { u64 line = 0; - for(u64 i = 0; i < fb.line_starts.length; i += 1) + for(u64 i = 0; i < fb.line_count; i += 1) { - if(fb.line_starts[i].pos > pos) + if(fb.lines[i].pos > pos) { break; } @@ -385,37 +437,32 @@ pragma(inline) u16 LevelFromPos(FlatBuffer* fb, u64 pos) { u64 line = LineFromPos(fb, pos); - return fb.line_starts[line].level; + return fb.lines[line].level; } pragma(inline) u64 LineLength(FlatBuffer* fb, u64 line) { - u64 len = 0; - if(line < fb.line_starts.length) - { - u64 start = fb.line_starts[line].pos; - u64 end = fb.line_starts.length-1 > line ? fb.line_starts[line+1].pos : fb.length; - len = end-start; - } - - return len; + return fb.lines[line].length; } void GetLines(FlatBuffer* fb, LineBuffers* linebufs, u64 length) { fb.rows = length; - GetLines(fb, linebufs, fb.offset, length); + GetLines(fb, linebufs, fb.line_offset, length); } pragma(inline) void -SliceLineBuffer(FlatBuffer* fb, LineBuffers* lbufs, LineBuffer* lbuf, u64 start, u64 len) +SliceLineBuffer(FlatBuffer* fb, LineBuffers* lbufs, LineStart* ls) { - lbuf.text = fb.data[start .. start+len]; - lbuf.style = fb.tk.buffer[start .. start+len]; + LineBuffer* lbuf = Alloc!(LineBuffer)(&lbufs.arena); + lbuf.text = fb.pbuf[ls.pos .. ls.pos+ls.length]; + lbuf.style = fb.tk.ptokens[ls.pos .. ls.pos+ls.length]; lbufs.count += 1; + + SLLPush(lbufs, lbuf, null); } void @@ -424,45 +471,26 @@ GetLines(FlatBuffer* fb, LineBuffers* linebufs, u64 start_line, u64 length) assert(linebufs != null, "GetLines failure: linebufs is null"); Reset(&linebufs.arena); - linebufs.first = Alloc!(LineBuffer)(&linebufs.arena); + linebufs.first = linebufs.last = null; linebufs.count = 0; - u64 total_lines = fb.line_starts.length; + u64 total_lines = fb.lines.length; linebufs.start = Min(start_line, total_lines); linebufs.end = Min(start_line + length, total_lines); if(fb.length == 0) { - linebufs.first.text = Alloc!(u8)(&linebufs.arena, 1); - linebufs.first.style = Alloc!(TS)(&linebufs.arena, 1); + SliceLineBuffer(fb, linebufs, &fb.lines[0]); } else if(linebufs.start == linebufs.end) with(fb) { - SliceLineBuffer(fb, linebufs, linebufs.first, line_starts[linebufs.start].pos, LineLength(fb, linebufs.start)); + SliceLineBuffer(fb, linebufs, &lines[linebufs.start]); } else with(linebufs) { - LineBuffer* current = first; for(u64 i = start; i < end; i += 1) { - u64 start_pos = fb.line_starts[i].pos; - u64 len = LineLength(fb, i); - - if(len > 0) - { - SliceLineBuffer(fb, linebufs, current, start_pos, len); - current.next = Alloc!(LineBuffer)(&arena); - current = current.next; - } - - if(i == fb.lf_count && fb.data[fb.length-1] == '\n') - { - current.text = Alloc!(u8)(&arena, 1); - current.style = Alloc!(TS)(&arena, 1); - count += 1; - - current.next = Alloc!(LineBuffer)(&arena); - } + SliceLineBuffer(fb, linebufs, &fb.lines[i]); } } } @@ -470,13 +498,13 @@ GetLines(FlatBuffer* fb, LineBuffers* linebufs, u64 start_line, u64 length) void MoveToEOL(FlatBuffer* fb) { - if(fb.data[fb.buf_pos] != '\n') + if(fb.pbuf[fb.pos] != '\n') { - for(u64 i = 0; i < fb.line_starts.length; i += 1) + for(u64 i = 0; i < fb.lines.length; i += 1) { - if(fb.buf_pos < fb.line_starts[i].pos) + if(fb.pos < fb.lines[i].pos) { - fb.buf_pos = 0 < i ? fb.line_starts[i].pos-1 : fb.length; + fb.pos = 0 < i ? fb.lines[i].pos-1 : fb.length; break; } } @@ -486,13 +514,13 @@ MoveToEOL(FlatBuffer* fb) void MoveToSOL(FlatBuffer* fb) { - if(fb.buf_pos != 0 && fb.data[fb.buf_pos-1] != '\n') + if(fb.pos != 0 && fb.pbuf[fb.pos-1] != '\n') { - for(u64 i = 0; i < fb.line_starts.length; i += 1) + for(u64 i = 0; i < fb.lines.length; i += 1) { - if(fb.buf_pos < fb.line_starts[i].pos) + if(fb.pos < fb.lines[i].pos) { - fb.buf_pos = i > 0 ? fb.line_starts[i-1].pos : 0; + fb.pos = i > 0 ? fb.lines[i-1].pos : 0; break; } } @@ -502,7 +530,7 @@ MoveToSOL(FlatBuffer* fb) void MoveUp(FlatBuffer* fb) { - MoveUp(fb, LinePos(fb, fb.buf_pos)); + MoveUp(fb, LinePos(fb, fb.pos)); } void @@ -511,28 +539,28 @@ MoveUp(FlatBuffer* fb, u64 col) u64 line = CurrentLine(fb); if(line > 0) { - u64 end = fb.line_starts[line].pos-1; + u64 end = fb.lines[line].pos-1; line -= 1; - fb.buf_pos = Min(fb.line_starts[line].pos+col, end); + fb.pos = Min(fb.lines[line].pos+col, end); } } void MoveDown(FlatBuffer* fb) { - MoveDown(fb, LinePos(fb, fb.buf_pos)); + MoveDown(fb, LinePos(fb, fb.pos)); } void MoveDown(FlatBuffer* fb, u64 col) { u64 line = CurrentLine(fb); - if(line+1 < fb.line_starts.length) + if(line+1 < fb.lines.length) { line += 1; - fb.buf_pos = fb.line_starts[line].pos; - u64 end = fb.line_starts.length > line+1 ? fb.line_starts[line+1].pos-1 : fb.length; - fb.buf_pos = Min(fb.buf_pos+col, end); + fb.pos = fb.lines[line].pos; + u64 end = fb.lines.length > line+1 ? fb.lines[line+1].pos-1 : fb.length; + fb.pos = Min(fb.pos+col, end); } } @@ -544,33 +572,33 @@ MoveToEmptyLine(bool up)(FlatBuffer* fb) u64 step = up ? -1 : 1; u8 ch = 0; - if((fb.buf_pos != 0 && up) || (fb.buf_pos != fb.length && !up)) + if((fb.pos != 0 && up) || (fb.pos != fb.length && !up)) { - for(u64 i = fb.buf_pos + step; true; i += step) + for(u64 i = fb.pos + step; true; i += step) { static if(!up) { if(i == fb.length-1) { - fb.buf_pos = fb.length; + fb.pos = fb.length; break; } - ch = fb.data[i]; + ch = fb.pbuf[i]; } static if(up) { if(i == 0) { - fb.buf_pos = 0; + fb.pos = 0; break; } - ch = fb.data[i-1]; + ch = fb.pbuf[i-1]; } - if(started && !CheckWhiteSpace(fb.data[i])) + if(started && !CheckWhiteSpace(fb.pbuf[i])) { started = false; } @@ -584,7 +612,7 @@ MoveToEmptyLine(bool up)(FlatBuffer* fb) if(started && ch == '\n') { - fb.buf_pos = i; + fb.pos = i; MoveToSOL(fb); break; } @@ -651,52 +679,52 @@ MoveToWordEdge(bool forward)(FlatBuffer* fb) { u64 step = forward ? 1 : -1; - if((forward && fb.buf_pos < fb.length-1) || (!forward && fb.buf_pos > 0)) + if((forward && fb.pos < fb.length-1) || (!forward && fb.pos > 0)) { - ChType type = GetChType(fb.data[fb.buf_pos]); - if(type != GetChType(fb.data[fb.buf_pos+step])) + ChType type = GetChType(fb.pbuf[fb.pos]); + if(type != GetChType(fb.pbuf[fb.pos+step])) { - fb.buf_pos += step; + fb.pos += step; } - else for(u64 i = fb.buf_pos+step; true; i += step) + else for(u64 i = fb.pos+step; true; i += step) { static if(forward) { - u8 next = i < fb.length-1 ? fb.data[i+1] : 0; + u8 next = i < fb.length-1 ? fb.pbuf[i+1] : 0; } else { - u8 next = i > 1 ? fb.data[i-1] : 0; + u8 next = i > 1 ? fb.pbuf[i-1] : 0; } static if(forward) if(i == fb.length-2) { - fb.buf_pos = i; - fb.buf_pos += u64(GetChType(next) == type); + fb.pos = i; + fb.pos += u64(GetChType(next) == type); break; } static if(!forward) if(i == 1) { - fb.buf_pos = i; - fb.buf_pos += GetChType(next) == type ? -1 : 0; + fb.pos = i; + fb.pos += GetChType(next) == type ? -1 : 0; break; } if(CheckChMatch(next, type)) { - fb.buf_pos = i; + fb.pos = i; break; } } - while(CheckWhiteSpace(fb.data[fb.buf_pos])) + while(CheckWhiteSpace(fb.pbuf[fb.pos])) { - bool exit = forward ? fb.buf_pos == fb.length-1 : fb.buf_pos == 0; + bool exit = forward ? fb.pos == fb.length-1 : fb.pos == 0; if(exit) break; - fb.buf_pos += step; + fb.pos += step; } } } @@ -704,25 +732,25 @@ MoveToWordEdge(bool forward)(FlatBuffer* fb) void MoveToNextWord(bool forward)(FlatBuffer* fb) { - ChType type = GetChType(fb.data[fb.buf_pos]); + ChType type = GetChType(fb.pbuf[fb.pos]); bool hit_ws; u64 step = forward ? 1 : -1; - for(u64 i = fb.buf_pos; true; i += step) with(ChType) + for(u64 i = fb.pos; true; i += step) with(ChType) { static if(forward) if(i == fb.length-1) { - fb.buf_pos = i; + fb.pos = i; break; } static if(!forward) if(i == 0) { - fb.buf_pos = i; + fb.pos = i; break; } - u8 ch = fb.data[i]; + u8 ch = fb.pbuf[i]; if(CheckWhiteSpace(ch)) { @@ -732,19 +760,19 @@ MoveToNextWord(bool forward)(FlatBuffer* fb) if(hit_ws) { - fb.buf_pos = i; + fb.pos = i; break; } if(CheckChMatch(ch, type)) { - fb.buf_pos = i; + fb.pos = i; break; } } - assert(fb.buf_pos >= 0 && fb.buf_pos <= fb.length); + assert(fb.pos >= 0 && fb.pos <= fb.length); } bool @@ -766,20 +794,20 @@ Move(FlatBuffer* fb, Input key, Modifier md) } break; case Left: { - if(fb.buf_pos > 0) + if(fb.pos > 0) { MoveToWordEdge!(false)(fb); } } break; case Right: { - if(fb.buf_pos < fb.length) + if(fb.pos < fb.length) { MoveToWordEdge!(true)(fb); } } break; - case Home: fb.buf_pos = 0; taken = true; break; - case End: fb.buf_pos = fb.length; taken = true; break; + case Home: fb.pos = 0; taken = true; break; + case End: fb.pos = fb.length; taken = true; break; default: break; } } @@ -795,14 +823,14 @@ Move(FlatBuffer* fb, Input key, Modifier md) } break; case Left: { - if(fb.buf_pos > 0) + if(fb.pos > 0) { MoveToNextWord!(false)(fb); } } break; case Right: { - if(fb.buf_pos < fb.length) + if(fb.pos < fb.length) { MoveToNextWord!(true)(fb); } @@ -826,17 +854,17 @@ Move(FlatBuffer* fb, Input key, Modifier md) } break; case Left: { - if(fb.buf_pos > 0 && fb.data[fb.buf_pos-1] != '\n') + if(fb.pos > 0 && fb.pbuf[fb.pos-1] != '\n') { - fb.buf_pos -= 1; + fb.pos -= 1; taken = true; } } break; case Right: { - if(fb.buf_pos < fb.length && fb.data[fb.buf_pos] != '\n') + if(fb.pos < fb.length && fb.pbuf[fb.pos] != '\n') { - fb.buf_pos += 1; + fb.pos += 1; taken = true; } } break; @@ -859,7 +887,7 @@ UpdateSelection(FlatBuffer* fb) { if(fb.sel_mode == SM.Normal) { - fb.sel.y = fb.buf_pos; + fb.sel.y = fb.pos; } if(fb.sel_mode == SM.Line) @@ -873,32 +901,32 @@ UpdateOffset(FlatBuffer* fb) { if(fb.rows > 0) with(fb) { - i64 screen_pos = CurrentLine(fb) - offset; + i64 screen_pos = CurrentLine(fb) - line_offset; i64 start = 0; i64 end = rows-2; Logf("p %s start %s end %s", screen_pos, start, end); - if(offset > 0 && screen_pos < start) + if(line_offset > 0 && screen_pos < start) { - offset += screen_pos; - Logf("scroll up %s", offset); + line_offset += screen_pos; + Logf("scroll up %s", line_offset); } else if(screen_pos > end) { - offset += screen_pos - end; - Logf("scroll down %s", offset); + line_offset += screen_pos - end; + Logf("scroll down %s", line_offset); } } - assert(fb.offset <= fb.lf_count); + assert(fb.line_offset <= fb.line_count); } void Backspace(FlatBuffer* fb) { - if(fb.buf_pos-1 >= 0) + if(fb.pos-1 >= 0) { - fb.buf_pos -= 1; - Delete(fb, 1, fb.buf_pos); + fb.pos -= 1; + Delete(fb, 1, fb.pos); } } @@ -910,9 +938,9 @@ Delete(FlatBuffer* fb, u64 length, u64 pos) for(u64 i = pos; i < fb.length && i < pos+length; i += 1) { - if(fb.data[i] == '\n') + if(fb.pbuf[i] == '\n') { - fb.lf_count -= 1; + fb.line_count -= 1; } } @@ -920,8 +948,8 @@ Delete(FlatBuffer* fb, u64 length, u64 pos) if(end != fb.length) { temp = Alloc!(u8)(&fb.arena, fb.length-end); - temp[0 .. temp.length] = fb.data[end .. fb.length]; - fb.data[pos .. pos+temp.length] = temp[0 .. temp.length]; + temp[0 .. temp.length] = fb.pbuf[end .. fb.length]; + fb.pbuf[pos .. pos+temp.length] = temp[0 .. temp.length]; } fb.length -= length; diff --git a/src/editor/editor.d b/src/editor/editor.d index 20045c7..a6608b5 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -319,7 +319,7 @@ SaveFile(Editor* ed, u8[] file_name) u64 tab_count; for(u64 i = 0; i < ed.buf.length; i += 1) { - if(ed.buf.data[i] == '\t') + if(ed.buf.pbuf[i] == '\t') { tab_count += 1; } @@ -332,7 +332,7 @@ SaveFile(Editor* ed, u8[] file_name) u64 buf_pos; for(u64 i = 0; i < ed.buf.length; i += 1) { - if(ed.buf.data[i] == '\t') + if(ed.buf.pbuf[i] == '\t') { for(u64 j = 0; j < tab_width; j += 1) { @@ -341,7 +341,7 @@ SaveFile(Editor* ed, u8[] file_name) } else { - temp_buf[buf_pos++] = ed.buf.data[i]; + temp_buf[buf_pos++] = ed.buf.pbuf[i]; } } @@ -373,7 +373,7 @@ OpenFile(Editor* ed, u8[] file_name) { u8[] buf = ScratchAlloc!(u8)(len); fread(buf.ptr, u8.sizeof, len, f); - Change(&ed.buf, buf); + Change(&ed.buf, buf, file_name); ed.buf.file_name = file_name; } @@ -394,7 +394,7 @@ CreateEditor(EditorCtx* ctx) Editor* ed = Alloc!(Editor)(&ctx.arena); ed.arena = CreateArena(MB(4)); - ed.buf = CreateFlatBuffer([]); + ed.buf = CreateFlatBuffer([], []); ed.linebufs = CreateLineBuffers(MB(1)); return ed; diff --git a/src/editor/parsing.d b/src/editor/parsing.d index cecc039..ae20889 100644 --- a/src/editor/parsing.d +++ b/src/editor/parsing.d @@ -389,7 +389,8 @@ struct Token struct Tokenizer { Arena arena; - TokenStyle[] buffer; + TokenStyle[] _tokens; + TokenStyle* ptokens; u64 tk_count; u64 pos; Token* first; @@ -402,14 +403,22 @@ Nil(Token* tk) return tk == g_NIL_TOKEN || tk == null; } +void +SetBuffers(Tokenizer* tk, TokenStyle[] tokens) +{ + tk._tokens = tokens; + tk.ptokens = tokens.ptr+BUF_START; +} + Tokenizer CreateTokenizer(FlatBuffer* fb) { Tokenizer tk = { arena: CreateArena(MB(4)), - buffer: Alloc!(TS)(fb.data.length), }; + SetBuffers(&tk, Alloc!(TS)(fb._buf.length)); + g_NIL_TOKEN = cast(Token*)&g_nil_tk; tk.first = tk.last = g_NIL_TOKEN; @@ -433,14 +442,14 @@ CreateTokenizer(FlatBuffer* fb) } void -ResetTokenizer(FlatBuffer* fb) +ResetTokenizer(Tokenizer* tk, u64 len) { - Reset(&fb.tk.arena); - Free(fb.tk.buffer); + Reset(&tk.arena); + Free(tk._tokens); - fb.tk.buffer = Alloc!(TS)(fb.data.length); - fb.tk.pos = 0; - fb.tk.first = fb.tk.last = g_NIL_TOKEN; + SetBuffers(tk, Alloc!(TS)(len)); + tk.pos = 0; + tk.first = tk.last = g_NIL_TOKEN; } Token* @@ -460,7 +469,7 @@ MakeToken(Tokenizer* tk, TokenType type, u64 start, u64 end) u8 Peek(FlatBuffer* fb) { - return fb.tk.pos+1 < fb.length ? fb.data[fb.tk.pos+1] : 0; + return fb.tk.pos+1 < fb.length ? fb.pbuf[fb.tk.pos+1] : 0; } void @@ -474,7 +483,7 @@ TokenizeD(FlatBuffer* fb) for(; tk.pos < fb.length;) { - u8 ch = fb.data[tk.pos]; + u8 ch = fb.pbuf[tk.pos]; bool alpha = (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); if(ch == ' ' || ch == '\t') @@ -483,7 +492,7 @@ TokenizeD(FlatBuffer* fb) for(tk.pos += 1; tk.pos < fb.length; tk.pos += 1) { - if(fb.data[tk.pos] != ' ' && fb.data[tk.pos] != '\t') + if(fb.pbuf[tk.pos] != ' ' && fb.pbuf[tk.pos] != '\t') { break; } @@ -568,7 +577,7 @@ TokenizeD(FlatBuffer* fb) for(; tk.pos < fb.length; tk.pos += 1) { - u8 c = fb.data[tk.pos]; + u8 c = fb.pbuf[tk.pos]; if(CheckWhiteSpace(c)) break; if(!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z')) break; @@ -582,7 +591,7 @@ TokenizeD(FlatBuffer* fb) for(; tk.pos < fb.length; tk.pos += 1) { - if(fb.data[tk.pos] != '.') break; + if(fb.pbuf[tk.pos] != '.') break; } t.end = tk.pos; @@ -593,7 +602,7 @@ TokenizeD(FlatBuffer* fb) for(; tk.pos < fb.length; tk.pos += 1) { - if(CheckWhiteSpace(fb.data[tk.pos])) break; + if(CheckWhiteSpace(fb.pbuf[tk.pos])) break; } t.end = tk.pos; @@ -610,7 +619,7 @@ TokenizeD(FlatBuffer* fb) for(; tk.pos < fb.length; tk.pos += 1) { - if(CheckEOL(fb.data[tk.pos])) + if(CheckEOL(fb.pbuf[tk.pos])) { break; } @@ -625,7 +634,7 @@ TokenizeD(FlatBuffer* fb) for(; tk.pos < fb.length; tk.pos += 1) { - if(fb.data[tk.pos] == '/' && fb.data[tk.pos-1] == '*') + if(fb.pbuf[tk.pos] == '/' && fb.pbuf[tk.pos-1] == '*') { break; } @@ -646,7 +655,7 @@ TokenizeD(FlatBuffer* fb) for(; tk.pos < fb.length; tk.pos += 1) { - if(CheckWhiteSpace(fb.data[tk.pos])) + if(CheckWhiteSpace(fb.pbuf[tk.pos])) { break; } @@ -707,7 +716,7 @@ TokenizeD(FlatBuffer* fb) for(auto token = tk.first; !Nil(token); token = token.next) { - tk.buffer[token.start .. token.end] = TOKEN_STYLES[token.type]; + tk.ptokens[token.start .. token.end] = TOKEN_STYLES[token.type]; } } @@ -817,7 +826,7 @@ CheckFuncOrTemplateSig(FlatBuffer* fb, Token* token) u8[] TokenStr(FlatBuffer* fb, Token* t) { - return fb.data[t.start .. t.end]; + return fb.pbuf[t.start .. t.end]; } Token* @@ -902,7 +911,7 @@ ParseNum(FlatBuffer* fb) { tk.pos += 1; - u8 ch = fb.data[tk.pos]; + u8 ch = fb.pbuf[tk.pos]; if(ch != '_' && ch != '.' && !(ch >= '0' && ch <= '9') && ch != 'x' && ch != 'X' && !((ch == '-' || ch == '+') && first)) { @@ -914,7 +923,7 @@ ParseNum(FlatBuffer* fb) while (tk.pos < fb.length) { - u8 ch = fb.data[tk.pos]; + u8 ch = fb.pbuf[tk.pos]; if(ch != 'l' && ch != 'u' && ch != 'U' && ch != 'L' && ch != 'f' && ch != 'F') { break; @@ -943,9 +952,9 @@ ParseStr(u8 str_ch)(FlatBuffer* fb) static if(str_ch == '`') tk.pos += 1; bool ignore = str_ch != '`'; - for(; (fb.data[tk.pos] != str_ch || ignore) && tk.pos < fb.length; tk.pos += 1) + for(; (fb.pbuf[tk.pos] != str_ch || ignore) && tk.pos < fb.length; tk.pos += 1) { - static if(str_ch != '`') ignore = fb.data[tk.pos] == '\\'; + static if(str_ch != '`') ignore = fb.pbuf[tk.pos] == '\\'; } tk.pos += 1; @@ -962,7 +971,7 @@ ParseId(FlatBuffer* fb) for(; tk.pos < fb.length; tk.pos += 1) { - u8 ch = fb.data[tk.pos]; + u8 ch = fb.pbuf[tk.pos]; if(!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && ch != '.' && ch != '_' && !(ch >= '0' && ch <= '9')) { @@ -971,11 +980,11 @@ ParseId(FlatBuffer* fb) } } - u8 ch = fb.data[t.start]; + u8 ch = fb.pbuf[t.start]; if(ch < D_KEYWORDS.length && D_KEYWORDS[ch] != null && D_KEYWORDS[ch].length > 0) { bool found = false; - u8[] id = fb.data[t.start .. t.end]; + u8[] id = fb.pbuf[t.start .. t.end]; foreach(ref k; D_TYPES[ch]) { @@ -1023,7 +1032,7 @@ FixOpAssign(FlatBuffer* fb, Token* t) { if(t.end+1 < fb.length) { - u8[] str = fb.data[t.start .. t.end+1]; + u8[] str = fb.pbuf[t.start .. t.end+1]; if( str == "/=" || str == "+=" || @@ -1066,7 +1075,7 @@ SkipWhiteSpace(FlatBuffer* fb) { while (fb.tk.pos < fb.length) { - u8 ch = fb.data[fb.tk.pos]; + u8 ch = fb.pbuf[fb.tk.pos]; bool white_space = CheckWhiteSpace(ch); diff --git a/src/editor/ui.d b/src/editor/ui.d index 0498fb0..d5332ce 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -465,11 +465,18 @@ Panel(UIPanel* panel) u64 ch_offset; auto parts = MakeMultiline(buf.text, code_view_width, buf.style); - for(auto n = parts; n != null; n = n.next) + if(parts == null) + { + if(pos.y == ed.buf.line_offset+i) + { + DrawCursor(atlas, [], 0, x+lcw+padding*2.0, y, ch_offset, edit); + } + } + else for(auto n = parts; n != null; n = n.next) { auto l = &n.value; - if(pos.y == ed.buf.offset+i) + if(pos.y == ed.buf.line_offset+i) { DrawCursor(atlas, l.text, pos.x, x+lcw+padding*2.0, y, ch_offset, edit); } @@ -511,7 +518,7 @@ pragma(inline) void DrawLineCount(FontAtlas* atlas, char[] fmt, f32* x_pos, f32 y, u64 line) { char[32] line_buf = '\0'; - char[] line_str = sformat(line_buf, fmt, line); + char[] line_str = sformat(line_buf, fmt, line+1); foreach(j; 0 .. line_str.length) { @@ -940,7 +947,7 @@ MakeMultiline(u8[] text, f32 width, TS[] style = []) if(ch_w + w > scaled_width || i == text.length-1) { - u64 len = i-start; + u64 len = i-start+1; u8[] str = ScratchAlloc!(u8)(text, start, len);