Skip to content

Commit

Permalink
Merge pull request #7 from OlegGulevskyy/caching-fixes
Browse files Browse the repository at this point in the history
Caching fixes
  • Loading branch information
OlegGulevskyy authored Dec 4, 2023
2 parents 51c487c + dbd7377 commit 7561c1a
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 25 deletions.
60 changes: 43 additions & 17 deletions lua/better-ts-errors/diagnostics.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
local parser = require("better-ts-errors.parser")
local codes = require("better-ts-errors.util.codes")
local severity = require("better-ts-errors.util.severity")
local strings = require("better-ts-errors.util.strings")
local strings_utils = require("better-ts-errors.util.strings")
local popup = require("better-ts-errors.popup")
local popup = require("better-ts-errors.popup")

Expand Down Expand Up @@ -37,22 +37,24 @@ end
-- Prepare body
M.handle_body = function(message, diag_count, index, current_line_num)
local normalized_line_nr = (current_line_num == 0) and 0 or (current_line_num - 1)
local message_start_pos = normalized_line_nr + 2
local message_start_row = normalized_line_nr + 2

local body_lines = strings.break_new_lines(message)
local body_lines = strings_utils.break_new_lines(message)
-- Ensure at least 2 rows for each message
if #body_lines < 2 then
table.insert(body_lines, "") -- Add an extra empty line
end

local new_body_lines = {}
local vars = {}
local i = 0
local added_lines_count = 0
local prettified_lines = {}

local line_index = 0
for _, line in ipairs(body_lines) do
local temp_vars = parser.get_variable_pos(line, message_start_pos + i)
local temp_vars = parser.get_variable_pos(line, message_start_row + line_index)
local has_raw_object = false
local identation_size = strings_utils.get_padding(line)

for _, temp_var in ipairs(temp_vars) do
if temp_var.is_raw_object then
Expand All @@ -62,20 +64,32 @@ M.handle_body = function(message, diag_count, index, current_line_num)
local part1 = string.sub(line, 1, temp_var.col_start)
local part2 = string.sub(line, temp_var.col_end + 1)

-- Calculate start position for prettified lines
-- Determine the starting row for the prettified lines
local prettified_start = message_start_row + #new_body_lines

-- Insert the first part into new_body_lines
if part1 ~= "" then
table.insert(new_body_lines, part1)
end

-- Insert the prettified lines
local lines = strings.break_new_lines(temp_var.match)
for _, k in ipairs(lines) do
table.insert(new_body_lines, k)
local lines = strings_utils.break_new_lines(temp_var.match)


for _, l in ipairs(lines) do
table.insert(new_body_lines, string.rep(" ", identation_size) .. l)
end

table.insert(prettified_lines, {
line_start = prettified_start + 2, -- +2 for the header
line_end = prettified_start + #lines - 1,
indentation = identation_size
})

-- Insert the second part into new_body_lines
if part2 ~= "" then
table.insert(new_body_lines, part2)
if part2 ~= "" and part2 ~= "." then
table.insert(new_body_lines, string.rep(" ", identation_size) .. part2)
end

added_lines_count = added_lines_count + #lines - 1
Expand All @@ -89,7 +103,7 @@ M.handle_body = function(message, diag_count, index, current_line_num)
table.insert(new_body_lines, line)
end

i = i + 1
line_index = line_index + 1
end

body_lines = new_body_lines
Expand All @@ -98,7 +112,7 @@ M.handle_body = function(message, diag_count, index, current_line_num)
local new_vars = {}
local line_i = 0
for _, line in ipairs(body_lines) do
local temp_vars = parser.get_variable_pos(line, message_start_pos + line_i)
local temp_vars = parser.get_variable_pos(line, message_start_row + line_i)
for _, temp_var in ipairs(temp_vars) do
table.insert(new_vars, temp_var)
end
Expand All @@ -113,10 +127,9 @@ M.handle_body = function(message, diag_count, index, current_line_num)
table.insert(body_lines, separator)
end

local message_end_pos = message_start_pos + #body_lines

vim.api.nvim_buf_set_lines(popup.get_buffnr(), message_start_pos, message_end_pos, false, body_lines)
return message_end_pos, new_vars
local message_end_pos = message_start_row + #body_lines
vim.api.nvim_buf_set_lines(popup.get_buffnr(), message_start_row, message_end_pos, false, body_lines)
return message_end_pos, new_vars, prettified_lines
end

M.show = function(is_enabled)
Expand All @@ -133,12 +146,15 @@ M.show = function(is_enabled)
local code_hl_ranges = {}
local vars_hl_ranges = {}
local current_line_num = 0
local prettified = nil

for index, diagnostic in ipairs(diagnostics) do
local header_lines, severity_pos, code_pos = M.handle_header(diagnostic.severity, diagnostic.code, #diagnostics,
current_line_num)

local message_end_pos, vars = M.handle_body(diagnostic.message, #diagnostics, index, current_line_num)
local message_end_pos, vars, prettified_ranges = M.handle_body(diagnostic.message, #diagnostics, index,
current_line_num)
prettified = prettified_ranges

table.insert(severity_hl_ranges, severity_pos)
table.insert(code_hl_ranges, code_pos)
Expand All @@ -165,6 +181,16 @@ M.show = function(is_enabled)
local hl_group = "String"
vim.api.nvim_buf_add_highlight(popup.get_buffnr(), -1, hl_group, range.line, range.col_start, range.col_end)
end

-- If we have some prettified objects, highlight them
if prettified ~= nil then
for _, range in ipairs(prettified) do
local hl_group = "BufferDefaultCurrentADDED"
for i = (range.line_start - 1), (range.line_end + 1) do
vim.api.nvim_buf_add_highlight(popup.get_buffnr(), -1, hl_group, i, range.indentation, popup.get_width())
end
end
end
end

return M
48 changes: 40 additions & 8 deletions lua/better-ts-errors/parser.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
local M = {}
local hash_util = require("better-ts-errors.util.hash")
local strings_util = require("better-ts-errors.util.strings")

local M = {
prettify_cache = {}
}

function allow_prettify()
if _G.BetterTsErrors.config ~= nil then
Expand Down Expand Up @@ -34,18 +39,45 @@ M.get_variable_pos = function(line, current_line_num)
return matches
end

function contains_union_type(str)
return string.find(str, "|")
end

function string_to_temp_ts_type(str)
return "type BTE_REPLACE_KEY = " .. str
end

-- Best effort for now
function temp_ts_type_to_string(str)
local pattern = "^type BTE_REPLACE_KEY =[%s%S](.*)"
local matched = string.match(str, pattern)
return matched or str
end

function prettify_string(str)
-- If JS object is too big, it will have "...;" in its children
-- Need to replace those temporarily, otherwise prettier will fail
local preprocess = str:gsub("(%.%.%.%;)", " REPLACE_KEY: null ")
local hashed = hash_util.simpleHash(str)
local has_union = contains_union_type(str)

if has_union then
str = string_to_temp_ts_type(str)
end

if M.prettify_cache[hashed] ~= nil then
return M.prettify_cache[hashed]
end

local preprocess = str:gsub("(%.%.%.%;)", " BTE_REPLACE_KEY: null ")
local command = "echo \"" .. preprocess .. "\" | prettier --parser typescript"

-- Execute the command and check for errors
local output, status = vim.fn.systemlist(command)

local output = vim.fn.systemlist(command)
if vim.v.shell_error == 0 then
-- Command executed successfully, process the output
local postprocess = table.concat(output, "\n"):gsub("(REPLACE_KEY: null)", "...")
local postprocess = table.concat(output, "\n"):gsub("(BTE_REPLACE_KEY: null)", "...")
if has_union then
postprocess = temp_ts_type_to_string(postprocess)
end

M.prettify_cache[hashed] = postprocess
return postprocess
else
-- Command failed, return the original string
Expand Down
12 changes: 12 additions & 0 deletions lua/better-ts-errors/util/hash.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
local M = {}

M.simpleHash = function(input)
local hash = 0
for i = 1, #input do
local char = string.byte(input, i)
hash = (hash * 31 + char) % 2 ^ 32
end
return hash
end

return M
12 changes: 12 additions & 0 deletions lua/better-ts-errors/util/strings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,16 @@ M.break_new_lines = function(message)
return body_lines
end

M.trim_string = function(str)
return string.match(str, "%s*(.-)%s*$")
end


-- Utility to calculate left pad for a given string
-- This should help us calculate the identation for a line of message
M.get_padding = function(str)
local whitespaces = string.match(str, "^%s*")
return #whitespaces
end

return M

0 comments on commit 7561c1a

Please sign in to comment.