~jamii/focus

3778c5e512c571f148454272041c1455c25696e0 — Jamie Brandon 10 months ago 4057a34
Use generic tree in buffer
M lib/focus/buffer.zig => lib/focus/buffer.zig +28 -28
@@ 3,7 3,7 @@ usingnamespace focus.common;
const App = focus.App;
const Editor = focus.Editor;
const meta = focus.meta;
const Tree = focus.Tree;
const BufferTree = focus.BufferTree;
const LineWrappedBuffer = focus.LineWrappedBuffer;

pub const BufferSource = union(enum) {


@@ 60,7 60,7 @@ const Edit = union(enum) {
pub const Buffer = struct {
    app: *App,
    source: BufferSource,
    tree: Tree,
    tree: BufferTree,
    undos: ArrayList([]Edit),
    doing: ArrayList(Edit),
    redos: ArrayList([]Edit),


@@ 75,7 75,7 @@ pub const Buffer = struct {
        self.* = Buffer{
            .app = app,
            .source = .None,
            .tree = Tree.init(app.allocator),
            .tree = BufferTree.init(app.allocator),
            .undos = ArrayList([]Edit).init(app.allocator),
            .doing = ArrayList(Edit).init(app.allocator),
            .redos = ArrayList([]Edit).init(app.allocator),


@@ 252,8 252,8 @@ pub const Buffer = struct {

    pub fn getLineColForPos(self: *Buffer, pos: usize) [2]usize {
        var point = self.tree.getPointForPos(pos).?;
        if (point.searchBackwards("\n") == .Found) _ = point.seekNextByte();
        return .{ point.getLine(), pos - point.pos };
        if (point.searchBackwards("\n") == .Found) _ = point.seekNextItem();
        return .{ BufferTree.getLine(point), pos - point.pos };
    }

    pub fn searchForwards(self: *Buffer, pos: usize, needle: []const u8) ?usize {


@@ 272,8 272,8 @@ pub const Buffer = struct {
        var point = self.tree.getPointForPos(pos).?;
        var num_closing: usize = 0;
        while (true) {
            if (point.seekPrevByte() == .NotFound) break;
            const char = point.getNextByte();
            if (point.seekPrevItem() == .NotFound) break;
            const char = point.getNextItem();
            if (isCloseParen(char)) num_closing += 1;
            if (isOpenParen(char)) num_closing -= 1;
            if (num_closing == 0) return point.pos;


@@ 285,11 285,11 @@ pub const Buffer = struct {
        var point = self.tree.getPointForPos(pos).?;
        var num_opening: usize = 0;
        while (true) {
            const char = point.getNextByte();
            const char = point.getNextItem();
            if (isCloseParen(char)) num_opening -= 1;
            if (isOpenParen(char)) num_opening += 1;
            if (num_opening == 0) return point.pos;
            if (point.seekNextByte() == .NotFound) break;
            if (point.seekNextItem() == .NotFound) break;
        }
        return null;
    }


@@ 297,13 297,13 @@ pub const Buffer = struct {
    pub fn matchParen(self: *Buffer, pos: usize) ?[2]usize {
        var point = self.tree.getPointForPos(pos).?;
        if (pos < self.getBufferEnd()) {
            if (isOpenParen(point.getNextByte()))
            if (isOpenParen(point.getNextItem()))
                if (self.matchParenForwards(pos)) |matching_pos|
                    return [2]usize{ pos, matching_pos };
        }
        if (pos > 0) {
            _ = point.seekPrevByte();
            if (isCloseParen(point.getNextByte()))
            _ = point.seekPrevItem();
            if (isCloseParen(point.getNextItem()))
                if (self.matchParenBackwards(pos)) |matching_pos|
                    return [2]usize{ pos - 1, matching_pos };
        }


@@ 312,7 312,7 @@ pub const Buffer = struct {

    pub fn getLineStart(self: *Buffer, pos: usize) usize {
        var point = self.tree.getPointForPos(pos).?;
        if (point.searchBackwards("\n") == .Found) _ = point.seekNextByte();
        if (point.searchBackwards("\n") == .Found) _ = point.seekNextItem();
        return point.pos;
    }



@@ 367,7 367,7 @@ pub const Buffer = struct {
        std.mem.reverse([][2]usize, line_colss.items);

        self.tree.deinit();
        self.tree = Tree.init(self.app.allocator);
        self.tree = BufferTree.init(self.app.allocator);
        self.tree.insert(0, new_bytes);

        self.modified_since_last_save = true;


@@ 510,10 510,10 @@ pub const Buffer = struct {
        //var point = self.tree.getPointForPos(0).?;
        //while (!point.isAtEnd()) {
        //const start = point.pos;
        //while (!point.isAtEnd() and isLikeIdent(point.getNextByte())) : (_ = point.seekNextByte()) {}
        //while (!point.isAtEnd() and isLikeIdent(point.getNextItem())) : (_ = point.seekNextItem()) {}
        //if (point.pos > start)
        //completions.append(self.tree.copy(self.app.allocator, start, point.pos)) catch oom();
        //while (!point.isAtEnd() and !isLikeIdent(point.getNextByte())) : (_ = point.seekNextByte()) {}
        //while (!point.isAtEnd() and !isLikeIdent(point.getNextItem())) : (_ = point.seekNextItem()) {}
        //}
        //
        //std.sort.sort([]const u8, completions.items, {}, struct {


@@ 528,7 528,7 @@ pub const Buffer = struct {
        //var point = self.tree.getPointForPos(range_start).?;
        //while (point.pos < range_end) {
        //const start = point.pos;
        //while (point.pos < range_end and isLikeIdent(point.getNextByte())) : (_ = point.seekNextByte()) {}
        //while (point.pos < range_end and isLikeIdent(point.getNextItem())) : (_ = point.seekNextItem()) {}
        //if (point.pos > start) {
        //const completions_items = completions.items;
        //const completion = self.tree.copy(self.app.frame_allocator, start, point.pos);


@@ 551,7 551,7 @@ pub const Buffer = struct {
        //const removed = completions.orderedRemove(pos);
        //self.app.allocator.free(removed);
        //}
        //while (point.pos < range_end and !isLikeIdent(point.getNextByte())) : (_ = point.seekNextByte()) {}
        //while (point.pos < range_end and !isLikeIdent(point.getNextItem())) : (_ = point.seekNextItem()) {}
        //}
    }



@@ 560,7 560,7 @@ pub const Buffer = struct {
        //var point = self.tree.getPointForPos(range_start).?;
        //while (point.pos < range_end) {
        //const start = point.pos;
        //while (point.pos < range_end and isLikeIdent(point.getNextByte())) : (_ = point.seekNextByte()) {}
        //while (point.pos < range_end and isLikeIdent(point.getNextItem())) : (_ = point.seekNextItem()) {}
        //if (point.pos > start) {
        //const completions_items = completions.items;
        //const completion = self.tree.copy(self.app.allocator, start, point.pos);


@@ 582,7 582,7 @@ pub const Buffer = struct {
        //
        //completions.insert(pos, completion) catch oom();
        //}
        //while (point.pos < range_end and !isLikeIdent(point.getNextByte())) : (_ = point.seekNextByte()) {}
        //while (point.pos < range_end and !isLikeIdent(point.getNextItem())) : (_ = point.seekNextItem()) {}
        //}
    }



@@ 618,9 618,9 @@ pub const Buffer = struct {
        var point = self.tree.getPointForPos(pos).?;
        const start = start: {
            while (true) {
                if (point.seekPrevByte() == .NotFound)
                if (point.seekPrevItem() == .NotFound)
                    break :start point.pos;
                if (!isLikeIdent(point.getNextByte()))
                if (!isLikeIdent(point.getNextItem()))
                    break :start point.pos + 1;
            }
        };


@@ 633,14 633,14 @@ pub const Buffer = struct {

        const start = start: {
            while (true) {
                if (start_point.seekPrevByte() == .NotFound)
                if (start_point.seekPrevItem() == .NotFound)
                    break :start start_point.pos;
                if (!isLikeIdent(start_point.getNextByte()))
                if (!isLikeIdent(start_point.getNextItem()))
                    break :start start_point.pos + 1;
            }
        };

        while (!end_point.isAtEnd() and isLikeIdent(end_point.getNextByte())) : (_ = end_point.seekNextByte()) {}
        while (!end_point.isAtEnd() and isLikeIdent(end_point.getNextItem())) : (_ = end_point.seekNextItem()) {}
        const end = end_point.pos;

        return self.tree.copy(self.app.frame_allocator, start, end);


@@ 652,13 652,13 @@ pub const Buffer = struct {
        var end_point = start_point;
        const start = start: {
            while (true) {
                if (start_point.seekPrevByte() == .NotFound)
                if (start_point.seekPrevItem() == .NotFound)
                    break :start start_point.pos;
                if (!isLikeIdent(start_point.getNextByte()))
                if (!isLikeIdent(start_point.getNextItem()))
                    break :start start_point.pos + 1;
            }
        };
        while (!end_point.isAtEnd() and isLikeIdent(end_point.getNextByte())) : (_ = end_point.seekNextByte()) {}
        while (!end_point.isAtEnd() and isLikeIdent(end_point.getNextItem())) : (_ = end_point.seekNextItem()) {}
        const end = end_point.pos;

        // replace completion

M lib/focus/buffer_tree.zig => lib/focus/buffer_tree.zig +6 -1
@@ 79,7 79,7 @@ const LeafState = struct {
    }
};

const BufferTree = struct {
pub const BufferTree = struct {
    inner: BufferTreeInner,

    pub fn init(allocator: *Allocator) BufferTree {


@@ 102,6 102,11 @@ const BufferTree = struct {
        self.inner.delete(&point, end - start);
    }

    pub fn copy(self: *BufferTree, allocator: *Allocator, start: usize, end: usize) []const u8 {
        var point = self.getPointForPos(start).?;
        return self.inner.copy(allocator, &point, end - start);
    }

    pub fn getPointForPos(self: BufferTree, pos: usize) ?BufferTreeInner.Point {
        var node = &self.inner.root.node;
        var pos_remaining = pos;

M lib/focus/editor.zig => lib/focus/editor.zig +7 -7
@@ 894,9 894,9 @@ pub const Editor = struct {
            self.goRealLineStart(edit_cursor);
            const this_line_start_pos = edit_cursor.head.pos;
            var this_line_start_point = self.buffer.tree.getPointForPos(this_line_start_pos).?;
            while (!this_line_start_point.isAtEnd() and this_line_start_point.getNextByte() == ' ') : (_ = this_line_start_point.seekNextByte()) {}
            while (!this_line_start_point.isAtEnd() and this_line_start_point.getNextItem() == ' ') : (_ = this_line_start_point.seekNextItem()) {}
            const this_indent = this_line_start_point.pos - this_line_start_pos;
            const line_start_char = if (!this_line_start_point.isAtEnd()) this_line_start_point.getNextByte() else 0;
            const line_start_char = if (!this_line_start_point.isAtEnd()) this_line_start_point.getNextItem() else 0;

            // work out prev line indent
            var prev_indent: usize = 0;


@@ 909,8 909,8 @@ pub const Editor = struct {
                    const end = self.buffer.getLineEnd(edit_cursor.head.pos);
                    var is_blank = true;
                    var point = self.buffer.tree.getPointForPos(start).?;
                    while (point.pos < end) : (_ = point.seekNextByte()) {
                        if (point.getNextByte() != ' ') {
                    while (point.pos < end) : (_ = point.seekNextItem()) {
                        if (point.getNextItem() != ' ') {
                            is_blank = false;
                            break;
                        }


@@ 919,12 919,12 @@ pub const Editor = struct {
                }

                const line_end_pos = self.buffer.getLineEnd(edit_cursor.head.pos);
                const line_end_char = if (line_end_pos > 0 and line_end_pos - 1 < self.buffer.getBufferEnd()) self.buffer.tree.getPointForPos(line_end_pos - 1).?.getNextByte() else 0;
                const line_end_char = if (line_end_pos > 0 and line_end_pos - 1 < self.buffer.getBufferEnd()) self.buffer.tree.getPointForPos(line_end_pos - 1).?.getNextItem() else 0;

                self.goRealLineStart(edit_cursor);
                const prev_line_start_pos = edit_cursor.head.pos;
                var prev_line_start_point = self.buffer.tree.getPointForPos(prev_line_start_pos).?;
                while (!prev_line_start_point.isAtEnd() and prev_line_start_point.getNextByte() == ' ') : (_ = prev_line_start_point.seekNextByte()) {}
                while (!prev_line_start_point.isAtEnd() and prev_line_start_point.getNextItem() == ' ') : (_ = prev_line_start_point.seekNextItem()) {}
                prev_indent = prev_line_start_point.pos - prev_line_start_pos;

                // add extra indent when opening a block


@@ 999,7 999,7 @@ pub const Editor = struct {
            self.goRealLineStart(edit_cursor);
            var line_start = edit_cursor.head.pos;
            var point = self.buffer.tree.getPointForPos(line_start).?;
            while (!point.isAtEnd() and point.getNextByte() == ' ') : (_ = point.seekNextByte()) {}
            while (!point.isAtEnd() and point.getNextItem() == ' ') : (_ = point.seekNextItem()) {}
            const start = point.pos;
            const end = self.buffer.getLineEnd(start);


M lib/focus/line_wrapped_buffer.zig => lib/focus/line_wrapped_buffer.zig +3 -3
@@ 47,7 47,7 @@ pub const LineWrappedBuffer = struct {
                                line_end = maybe_line_end.pos;
                                break;
                            }
                            const char = maybe_line_end.getNextByte();
                            const char = maybe_line_end.getNextItem();
                            if (maybe_line_end.pos - line_start > self.max_chars_per_line) {
                                // if we haven't soft wrapped yet, hard wrap before this char, otherwise use soft wrap
                                if (line_end == line_start) {


@@ 60,7 60,7 @@ pub const LineWrappedBuffer = struct {
                                line_end = maybe_line_end.pos;
                                break;
                            }
                            _ = maybe_line_end.seekNextByte();
                            _ = maybe_line_end.seekNextItem();
                            if (char == ' ') {
                                // commit to including this char
                                line_end = maybe_line_end.pos;


@@ 75,7 75,7 @@ pub const LineWrappedBuffer = struct {
            }

            if (point.isAtEnd()) break;
            _ = point.seekNextByte();
            _ = point.seekNextItem();
        }
    }


M lib/focus/tree.zig => lib/focus/tree.zig +6 -9
@@ 204,29 204,26 @@ pub fn Tree(comptime _config: TreeConfig) type {
            return depth;
        }

        pub fn copy(self: TreeSelf, allocator: *Allocator, start: usize, end: usize) []const config.Item {
            var buffer = allocator.alloc(config.Item, end - start) catch oom();
        pub fn copy(self: TreeSelf, allocator: *Allocator, start: *Point, len: usize) []const config.Item {
            var buffer = allocator.alloc(config.Item, len) catch oom();
            self.copyInto(buffer, start);
            return buffer;
        }

        pub fn copyInto(self: TreeSelf, _buffer: []config.Item, start: usize) void {
        pub fn copyInto(self: TreeSelf, _buffer: []config.Item, start: *Point) void {
            var buffer = _buffer;

            var point = self.getPointForPos(start).?;

            while (true) {
                const num_copy_items = min(buffer.len, point.leaf.num_items - point.offset);
                const num_copy_items = min(buffer.len, start.leaf.num_items - start.offset);
                std.mem.copy(
                    config.Item,
                    buffer,
                    point.leaf.items[point.offset .. point.offset + num_copy_items],
                    start.leaf.items[start.offset .. start.offset + num_copy_items],
                );
                buffer = buffer[num_copy_items..];

                if (buffer.len == 0) break;

                assert(point.seekNextLeaf() != .NotFound);
                assert(start.seekNextLeaf() != .NotFound);
            }
        }