Skip to content

Commit

Permalink
Fix styles that affect multiple lines
Browse files Browse the repository at this point in the history
  • Loading branch information
m00qek committed May 31, 2024
1 parent 026ac78 commit 7d6c862
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 30 deletions.
27 changes: 14 additions & 13 deletions lua/baleia/locations/ansi_codes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ local M = {}
---@return Location[]
function M.ignore(locations)
for _, location in ipairs(locations) do
location.from.column = location.from.column + location.style.offset
location.from.column = location.from.column + location.from.offset
end

return locations
Expand All @@ -13,24 +13,25 @@ end
---@param locations Location[]
---@return Location[]
function M.strip(locations)
local line_number = locations[1].to.line
local offset = 0
local current_line = 0
local lineoffset = 0

for _, location in ipairs(locations) do
if line_number ~= location.from.line then
line_number = location.from.line
offset = 0
if current_line ~= location.from.line then
current_line = location.from.line
lineoffset = 0
end

location.from.column = location.from.column - offset
offset = offset + location.style.offset
location.from.column = location.from.column - lineoffset

if not location.to.column or line_number ~= location.to.line then
line_number = location.to.line
offset = 0
else
location.to.column = location.to.column - offset
if location.from.line ~= location.to.line then
current_line = location.to.line
lineoffset = 0
end

print(location.from.column, lineoffset)
lineoffset = lineoffset + location.to.offset
location.to.column = location.to.column - lineoffset
end

return locations
Expand Down
15 changes: 12 additions & 3 deletions lua/baleia/locations/neighbours.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ local function can_merge(previous, current)
local no_text_between_locations = current.from.column == previous.from.column + previous.style.offset

local current_location_at_start = current.from.column == 1
local previous_location_at_the_end = previous.to.column == nil
local previous_location_at_the_end = previous.to.column == previous.from.column + previous.style.offset - 1

return (on_the_same_line and no_text_between_locations)
or (in_different_lines and current_location_at_start and previous_location_at_the_end)
Expand All @@ -23,14 +23,23 @@ end
---@return Location
local function merge(previous, current)
local style = styles.merge(previous.style, current.style)

local from = previous.from
local to = current.to

if current.from.line == previous.from.line then
style.offset = previous.style.offset + current.style.offset
to.offset = previous.to.offset + current.to.offset
from.offset = previous.from.offset + current.from.offset
else
to.offset = current.to.offset
from.offset = previous.from.offset
end

return {
style = style,
from = previous.from,
to = current.to,
from = from,
to = to,
}
end

Expand Down
31 changes: 23 additions & 8 deletions lua/baleia/locations/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local styles = require("baleia.styles")
---@class StrictPosition
---@field line integer
---@field column integer
---@field offset integer?

---@class LoosePosition
---@field line integer
Expand All @@ -12,17 +13,21 @@ local styles = require("baleia.styles")
---@field text string
---@field style Style
---@field from StrictPosition
---@field to LoosePosition
---@field to StrictPosition

local M = {}

local function rpairs(table)
--- Reverses a list.
---@generic T
---@param list T[]
---@return (fun(t: T[], i: integer): integer?, T?), T[], integer
local function rpairs(list)
return function(t, i)
i = i - 1
if i ~= 0 then
return i, t[i]
end
end, table, #table + 1
end, list, #list + 1
end

---@param line_number integer
Expand All @@ -34,9 +39,10 @@ local function parse_line(line_number, text)
local position = 1
for ansi_sequence in string.gmatch(text, styles.ANSI_CODES_PATTERN) do
local column_number = string.find(text, styles.ANSI_CODES_PATTERN, position)
local style = styles.to_style(ansi_sequence)
table.insert(locations, {
style = styles.to_style(ansi_sequence),
from = { line = line_number, column = column_number },
style = style,
from = { line = line_number, column = column_number, offset = style.offset },
})
position = column_number + 1
end
Expand All @@ -48,20 +54,29 @@ end
---@return Location[]
local function parse_all(lines)
local lastline = #lines
local lastcolumn = nil
local lastcolumn = #lines[lastline]

local locations = {}

for line_number, current_line in rpairs(lines) do
for _, current_location in rpairs(parse_line(line_number, current_line)) do
current_location.to = { line = lastline, column = lastcolumn }
current_location.to = {
line = lastline,
column = lastcolumn,
offset = lastline == current_location.from.line and current_location.style.offset or 0,
}
table.insert(locations, current_location)

lastline = line_number
lastcolumn = current_location.from.column - 1
if lastcolumn < 1 then
lastline = lastline - 1
lastcolumn = nil

if lines[lastline] then
lastcolumn = #lines[lastline]
else
lastcolumn = 0
end
end
end
end
Expand Down
26 changes: 20 additions & 6 deletions test/spec/baleia/locations_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,37 @@ local locations = require("baleia.locations")

describe("[merge_neighbours]", function()
it("Two codes,in the **same** line, without text between them", function()
local locs = locations.extract({ strip_ansi_codes = true }, {}, { "\x1b[0m\x1b[31mfirst line" })
local locs = locations.extract({ strip_ansi_codes = true }, {}, { "\x1b[0m\x1b[31mfirst \x1b[0mline" })
assert.combinators.match({
{
style = { offset = 9 },
from = { line = 1, column = 1 },
to = { line = 1 },
to = { line = 1, column = 6 },
},
{
style = { offset = 4 },
from = { line = 1, column = 7 },
to = { line = 1, column = 10 },
},
}, locs)
end)

it("Two codes,in **different** line, without text between them", function()
local locs = locations.extract({ strip_ansi_codes = true }, {}, { "first line\x1b[1m", "\x1b[31msecond line" })
local locs = locations.extract(
{ strip_ansi_codes = true },
{},
{ "first line\x1b[1m", "\x1b[31msecond \x1b[0mline" }
)
assert.combinators.match({
{
style = { offset = 5 },
from = { line = 1, column = 11 },
to = { line = 2 },
to = { line = 2, column = 7 },
},
{
style = { offset = 4 },
from = { line = 2, column = 8 },
to = { line = 2, column = 11 },
},
}, locs)
end)
Expand Down Expand Up @@ -53,8 +67,8 @@ describe("[extract]", function()
it("with blank line between", function()
local lines = { "first line\x1b[0m", "second line", "third \x1b[0mline" }
assert.combinators.match({
{ from = { line = 1, column = 11 }, to = { line = 3 } },
{ from = { line = 3, column = 7 }, to = { line = 3 } },
{ from = { line = 1, column = 11 }, to = { line = 3, column = 6 } },
{ from = { line = 3, column = 7 }, to = { line = 3, column = 10 } },
}, locations.extract({ strip_ansi_codes = true }, {}, lines))
end)

Expand Down

0 comments on commit 7d6c862

Please sign in to comment.