add auto indenting

This commit is contained in:
Matthew 2025-09-30 05:32:16 +10:00
parent bfa5cee407
commit 8896b84611
2 changed files with 121 additions and 25 deletions

View File

@ -16,7 +16,7 @@
"versions": [],
"preGenerateCommands-linux": ["./build.sh"],
"preGenerateCommands-windows": [],
"dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-Jbuild", "-Jassets"],
"dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-Jbuild", "-Jassets", "-link-debuglib"],
"dflags-dmd": ["-P=-DSTBI_NO_SIMD"]
},
]

View File

@ -6,17 +6,23 @@ import std.math.algebraic : abs;
struct FlatBuffer
{
Tokenizer tk;
Arena arena;
u8[] data;
Arena ls_arena;
u64[] line_starts;
u64 length;
u64 lf_count;
i64 buf_pos;
i64 offset;
i64 rows;
bool dirty;
Tokenizer tk;
Arena arena;
u8[] data;
Arena ls_arena;
LineStart[] line_starts;
u64 length;
u64 lf_count;
i64 buf_pos;
i64 offset;
i64 rows;
bool dirty;
}
struct LineStart
{
u64 pos;
u16 level;
}
struct LineBuffers
@ -102,15 +108,51 @@ Fix(FlatBuffer* buffer)
with(buffer)
{
Reset(&ls_arena);
line_starts = AllocArray!(u64)(&ls_arena, lf_count+1);
line_starts[0] = 0;
line_starts = AllocArray!(LineStart)(&ls_arena, lf_count+1);
line_starts[0].pos = 0;
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(pending_level > 0)
{
ignore += 1;
}
else
{
pending_level = 1;
}
}
if(data[i] == '}' || data[i] == ')' || data[i] == ']')
{
if(ignore > 0)
{
ignore -= 1;
}
else if(pending_level == 1)
{
pending_level = 0;
}
else if(level > 0)
{
level -= 1;
}
}
if(data[i] == '\n')
{
line_starts[ls_idx] = i+1;
level += pending_level;
pending_level = 0;
line_starts[ls_idx].pos = i+1;
line_starts[ls_idx].level = level;
Logf("line %s level %s", ls_idx, line_starts[ls_idx].level);
ls_idx += 1;
}
}
@ -149,6 +191,50 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos)
}
}
if(length == 1)
{
u8 new_ch;
switch(insert[0])
{
case '[': new_ch = ']'; break;
case '(': new_ch = ')'; break;
case '{': new_ch = '}'; break;
case '\'', '"', '`', '\n': new_ch = insert[0]; break;
default: break;
}
if(new_ch == '\n' && pos > 0)
{
u8 l = fb.data[pos-1];
u8 r = fb.data[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)
{
insert[length] = '\t';
}
if(expand)
{
insert[length++] = '\n';
fb.lf_count += 1;
limit = level-1+length;
for(; length < limit; length += 1)
{
insert[length] = '\t';
}
}
}
else if(new_ch > 0)
{
length += 1;
insert[1] = new_ch;
}
}
u64 temp_len = fb.length-pos;
u8[] temp = AllocArray!(u8)(&fb.arena, temp_len);
@ -158,9 +244,12 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos)
fb.data[pos .. pos+temp_len] = temp[0 .. temp_len];
fb.length += length;
Logf("out");
Fix(fb);
Logf("out");
Reset(&fb.arena);
AdjustOffset(fb);
@ -188,7 +277,7 @@ pragma(inline) u64
LinePos(FlatBuffer* fb, u64 pos)
{
u64 line = LineFromPos(fb, pos);
return pos - fb.line_starts[line];
return pos - fb.line_starts[line].pos;
}
pragma(inline) U64Vec2
@ -203,7 +292,7 @@ LineFromPos(FlatBuffer* fb, u64 pos)
u64 line = 0;
for(u64 i = 0; i < fb.line_starts.length; i += 1)
{
if(fb.line_starts[i] > pos)
if(fb.line_starts[i].pos > pos)
{
break;
}
@ -214,14 +303,21 @@ LineFromPos(FlatBuffer* fb, u64 pos)
return line;
}
pragma(inline) u16
LevelFromPos(FlatBuffer* fb, u64 pos)
{
u64 line = LineFromPos(fb, pos);
return fb.line_starts[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];
u64 end = fb.line_starts.length-1 > line ? fb.line_starts[line+1] : fb.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;
}
@ -254,7 +350,7 @@ GetLines(FlatBuffer* buffer, LineBuffers* linebufs, u64 start_line, u64 length)
}
else if(start_line == end_line) with(buffer)
{
u64 start_of_line = line_starts[start_line];
u64 start_of_line = line_starts[start_line].pos;
u64 len = LineLength(buffer, start_line);
linebufs.first.text = AllocArray!(u8)(&linebufs.arena, len);
@ -273,7 +369,7 @@ GetLines(FlatBuffer* buffer, LineBuffers* linebufs, u64 start_line, u64 length)
LineBuffer* current = first;
for(u64 i = start_line; i < end_line; i += 1)
{
u64 start = buffer.line_starts[i];
u64 start = buffer.line_starts[i].pos;
u64 len = LineLength(buffer, i);
if(len > 0)
@ -317,9 +413,9 @@ MoveUp(FlatBuffer* fb, u64 col)
u64 line = CurrentLine(fb);
if(line > 0)
{
u64 end = fb.line_starts[line]-1;
u64 end = fb.line_starts[line].pos-1;
line -= 1;
fb.buf_pos = Min(fb.line_starts[line]+col, end);
fb.buf_pos = Min(fb.line_starts[line].pos+col, end);
}
}
@ -336,8 +432,8 @@ MoveDown(FlatBuffer* fb, u64 col)
if(line+1 < fb.line_starts.length)
{
line += 1;
fb.buf_pos = fb.line_starts[line];
u64 end = fb.line_starts.length > line+1 ? fb.line_starts[line+1]-1 : fb.length;
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);
}
}