From 50e55afa99aa9feca294a5178bad9fcb42efb704 Mon Sep 17 00:00:00 2001 From: Jackson Moore Date: Fri, 4 Sep 2026 17:57:21 +0200 Subject: Index text snapshots lazily by line --- lua/clever_f/text_topology.lua | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'lua') diff --git a/lua/clever_f/text_topology.lua b/lua/clever_f/text_topology.lua index 56f3b9c..37365a0 100644 --- a/lua/clever_f/text_topology.lua +++ b/lua/clever_f/text_topology.lua @@ -324,22 +324,14 @@ function TextView.new(text, effective_encoding, options) ) local encoder = selected_function(options, "encoder", "encode", default_encode) - local lines = {} - for line_number = 1, snapshot.line_count do - lines[line_number] = index_line( - snapshot:line(line_number), - encoding, - splitter, - encoder - ) - end - local view = setmetatable({}, text_view_metatable) view_records[view] = { snapshot = snapshot, requested_encoding = requested_encoding, encoding = encoding, - lines = lines, + splitter = splitter, + encoder = encoder, + lines = {}, } return view end @@ -375,7 +367,17 @@ local function line_record(view, line_number) then fail("line_number must identify a line in the TextView", 3) end - return record.lines[line_number] + local line = record.lines[line_number] + if line == nil then + line = index_line( + record.snapshot:line(line_number), + record.encoding, + record.splitter, + record.encoder + ) + record.lines[line_number] = line + end + return line end local function require_character_index(line, character_index) @@ -433,7 +435,7 @@ function TextView:text_suffix(position) end for line_number = position.line + 1, record.snapshot.line_count do parts[#parts + 1] = "\n" - parts[#parts + 1] = record.lines[line_number].text + parts[#parts + 1] = record.snapshot:line(line_number) end return table.concat(parts) end @@ -540,7 +542,7 @@ function TextView:is_character_start(position_or_line, byte_column) if line_number > record.snapshot.line_count then return false end - return record.lines[line_number].by_start[column] ~= nil + return line_record(self, line_number).by_start[column] ~= nil end function TextView:is_valid_cursor_position(position_or_line, byte_column) @@ -549,7 +551,7 @@ function TextView:is_valid_cursor_position(position_or_line, byte_column) if line_number > record.snapshot.line_count then return false end - local line = record.lines[line_number] + local line = line_record(self, line_number) if line.character_count == 0 then return column == 1 end @@ -740,7 +742,7 @@ function TextView:buffer_match_start_bounds() local last for line_number = 1, record.snapshot.line_count do - local line = record.lines[line_number] + local line = line_record(self, line_number) if line.character_count > 0 then first = self:position_for_character_index(line_number, 1) break @@ -748,7 +750,7 @@ function TextView:buffer_match_start_bounds() end for line_number = record.snapshot.line_count, 1, -1 do - local line = record.lines[line_number] + local line = line_record(self, line_number) if line.character_count > 0 then last = self:position_for_character_index(line_number, line.character_count) break @@ -810,7 +812,7 @@ end local function step_character(view, position, direction) local record = view_record(view) - local line = record.lines[position.line] + local line = line_record(view, position.line) local character_index = line.by_start[position.byte_column] if direction == domain.Direction.FORWARD then @@ -818,7 +820,7 @@ local function step_character(view, position, direction) return view:position_for_character_index(position.line, character_index + 1) end for line_number = position.line + 1, record.snapshot.line_count do - if record.lines[line_number].character_count > 0 then + if line_record(view, line_number).character_count > 0 then return view:position_for_character_index(line_number, 1) end end @@ -829,7 +831,7 @@ local function step_character(view, position, direction) return view:position_for_character_index(position.line, character_index - 1) end for line_number = position.line - 1, 1, -1 do - local previous_line = record.lines[line_number] + local previous_line = line_record(view, line_number) if previous_line.character_count > 0 then return view:position_for_character_index( line_number, -- cgit v1.2.3