feat: support loading extreamly large files
- Allocate initial file and leaf data outside of Buffer.arena - Disable gutter diffs for very large files - Disable syntax highlighting for very large files
This commit is contained in:
parent
7332108820
commit
b09aa98f70
4 changed files with 32 additions and 11 deletions
|
@ -28,6 +28,8 @@ arena: std.heap.ArenaAllocator,
|
||||||
a: Allocator,
|
a: Allocator,
|
||||||
external_a: Allocator,
|
external_a: Allocator,
|
||||||
root: Root,
|
root: Root,
|
||||||
|
leaves_buf: ?[]Node = null,
|
||||||
|
file_buf: ?[]const u8 = null,
|
||||||
file_path: []const u8 = "",
|
file_path: []const u8 = "",
|
||||||
last_save: ?Root = null,
|
last_save: ?Root = null,
|
||||||
file_exists: bool = true,
|
file_exists: bool = true,
|
||||||
|
@ -1023,6 +1025,8 @@ pub fn create(a: Allocator) !*Self {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
|
if (self.file_buf) |buf| self.external_a.free(buf);
|
||||||
|
if (self.leaves_buf) |buf| self.external_a.free(buf);
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
self.external_a.destroy(self);
|
self.external_a.destroy(self);
|
||||||
}
|
}
|
||||||
|
@ -1034,8 +1038,10 @@ fn new_file(self: *const Self, file_exists: *bool) !Root {
|
||||||
|
|
||||||
pub fn load(self: *const Self, reader: anytype, size: usize) !Root {
|
pub fn load(self: *const Self, reader: anytype, size: usize) !Root {
|
||||||
const eol = '\n';
|
const eol = '\n';
|
||||||
var buf = try self.a.alloc(u8, size);
|
var buf = try self.external_a.alloc(u8, size);
|
||||||
const read_size = try reader.read(buf);
|
const self_ = @constCast(self);
|
||||||
|
self_.file_buf = buf;
|
||||||
|
const read_size = try reader.readAll(buf);
|
||||||
if (read_size != size)
|
if (read_size != size)
|
||||||
return error.BufferUnderrun;
|
return error.BufferUnderrun;
|
||||||
const final_read = try reader.read(buf);
|
const final_read = try reader.read(buf);
|
||||||
|
@ -1047,7 +1053,8 @@ pub fn load(self: *const Self, reader: anytype, size: usize) !Root {
|
||||||
if (buf[i] == eol) leaf_count += 1;
|
if (buf[i] == eol) leaf_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var leaves = try self.a.alloc(Node, leaf_count);
|
var leaves = try self.external_a.alloc(Node, leaf_count);
|
||||||
|
self_.leaves_buf = leaves;
|
||||||
var cur_leaf: usize = 0;
|
var cur_leaf: usize = 0;
|
||||||
var b: usize = 0;
|
var b: usize = 0;
|
||||||
for (0..buf.len) |i| {
|
for (0..buf.len) |i| {
|
||||||
|
|
|
@ -13,6 +13,9 @@ const c = @cImport({
|
||||||
const build_options = @import("build_options");
|
const build_options = @import("build_options");
|
||||||
const log = @import("log");
|
const log = @import("log");
|
||||||
|
|
||||||
|
pub var max_diff_lines: usize = 50000;
|
||||||
|
pub var max_syntax_lines: usize = 50000;
|
||||||
|
|
||||||
pub const application_name = "flow";
|
pub const application_name = "flow";
|
||||||
pub const application_logo = " ";
|
pub const application_logo = " ";
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ const text_manip = @import("text_manip");
|
||||||
const syntax = @import("syntax");
|
const syntax = @import("syntax");
|
||||||
const project_manager = @import("project_manager");
|
const project_manager = @import("project_manager");
|
||||||
const CaseData = @import("CaseData");
|
const CaseData = @import("CaseData");
|
||||||
|
const root_mod = @import("root");
|
||||||
|
|
||||||
const Plane = @import("renderer").Plane;
|
const Plane = @import("renderer").Plane;
|
||||||
const Cell = @import("renderer").Cell;
|
const Cell = @import("renderer").Cell;
|
||||||
|
@ -403,17 +404,21 @@ pub const Editor = struct {
|
||||||
if (self.buffer) |_| try self.close();
|
if (self.buffer) |_| try self.close();
|
||||||
self.buffer = new_buf;
|
self.buffer = new_buf;
|
||||||
|
|
||||||
|
self.syntax = syntax: {
|
||||||
|
if (new_buf.root.lines() > root_mod.max_syntax_lines)
|
||||||
|
break :syntax null;
|
||||||
|
const lang_override = tp.env.get().str("language");
|
||||||
var content = std.ArrayList(u8).init(self.a);
|
var content = std.ArrayList(u8).init(self.a);
|
||||||
defer content.deinit();
|
defer content.deinit();
|
||||||
try new_buf.root.store(content.writer());
|
try new_buf.root.store(content.writer());
|
||||||
self.syntax = syntax: {
|
const syn = if (lang_override.len > 0)
|
||||||
const lang_override = tp.env.get().str("language");
|
syntax.create_file_type(self.a, content.items, lang_override) catch null
|
||||||
if (lang_override.len > 0)
|
else
|
||||||
break :syntax syntax.create_file_type(self.a, content.items, lang_override) catch null;
|
syntax.create_guess_file_type(self.a, content.items, self.file_path) catch null;
|
||||||
break :syntax syntax.create_guess_file_type(self.a, content.items, self.file_path) catch null;
|
if (syn) |syn_|
|
||||||
|
project_manager.did_open(file_path, syn_.file_type, self.lsp_version, try content.toOwnedSlice()) catch {};
|
||||||
|
break :syntax syn;
|
||||||
};
|
};
|
||||||
if (self.syntax) |syn|
|
|
||||||
project_manager.did_open(file_path, syn.file_type, self.lsp_version, try content.toOwnedSlice()) catch {};
|
|
||||||
|
|
||||||
const ftn = if (self.syntax) |syn| syn.file_type.name else "text";
|
const ftn = if (self.syntax) |syn| syn.file_type.name else "text";
|
||||||
const fti = if (self.syntax) |syn| syn.file_type.icon else "🖹";
|
const fti = if (self.syntax) |syn| syn.file_type.icon else "🖹";
|
||||||
|
@ -2907,6 +2912,8 @@ pub const Editor = struct {
|
||||||
defer frame.deinit();
|
defer frame.deinit();
|
||||||
const root = try self.buf_root();
|
const root = try self.buf_root();
|
||||||
const token = @intFromPtr(root);
|
const token = @intFromPtr(root);
|
||||||
|
if (root.lines() > root_mod.max_syntax_lines)
|
||||||
|
return;
|
||||||
if (self.syntax_token == token)
|
if (self.syntax_token == token)
|
||||||
return;
|
return;
|
||||||
if (self.syntax) |syn| {
|
if (self.syntax) |syn| {
|
||||||
|
|
|
@ -300,6 +300,10 @@ fn mouse_click_button5(_: *Self) error{Exit}!bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn diff_update(self: *Self) !void {
|
fn diff_update(self: *Self) !void {
|
||||||
|
if (self.lines > root.max_diff_lines) {
|
||||||
|
self.diff_symbols_clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
const editor = self.editor;
|
const editor = self.editor;
|
||||||
const new = if (editor.get_current_root()) |new| new else return;
|
const new = if (editor.get_current_root()) |new| new else return;
|
||||||
const old = if (editor.buffer) |buffer| if (buffer.last_save) |old| old else return else return;
|
const old = if (editor.buffer) |buffer| if (buffer.last_save) |old| old else return else return;
|
||||||
|
|
Loading…
Add table
Reference in a new issue