mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-24 06:34:09 +00:00
Add whitespace change detection utility and integrate into PatchTree. Enhanced PatchTree to count line changes specifically for Source properties, distinguishing between total and whitespace-only changes. Updated theme colors for visual representation of whitespace changes in the UI.
This commit is contained in:
parent
00872e65a4
commit
9bedbd70fd
4 changed files with 128 additions and 24 deletions
|
|
@ -17,6 +17,40 @@ local ChangeList = require(script.Parent.ChangeList)
|
||||||
local Tooltip = require(Plugin.App.Components.Tooltip)
|
local Tooltip = require(Plugin.App.Components.Tooltip)
|
||||||
local ClassIcon = require(Plugin.App.Components.ClassIcon)
|
local ClassIcon = require(Plugin.App.Components.ClassIcon)
|
||||||
|
|
||||||
|
local function ChangeTag(props)
|
||||||
|
return Theme.with(function(theme)
|
||||||
|
local tagColor = props.color or theme.SubTextColor
|
||||||
|
return e("Frame", {
|
||||||
|
Size = UDim2.new(0, 0, 0, 16),
|
||||||
|
AutomaticSize = Enum.AutomaticSize.X,
|
||||||
|
BackgroundColor3 = tagColor,
|
||||||
|
BackgroundTransparency = props.transparency:map(function(t)
|
||||||
|
return 0.85 + (0.15 * t)
|
||||||
|
end),
|
||||||
|
LayoutOrder = props.layoutOrder or 1,
|
||||||
|
}, {
|
||||||
|
Corner = e("UICorner", {
|
||||||
|
CornerRadius = UDim.new(0, 3),
|
||||||
|
}),
|
||||||
|
Padding = e("UIPadding", {
|
||||||
|
PaddingLeft = UDim.new(0, 5),
|
||||||
|
PaddingRight = UDim.new(0, 5),
|
||||||
|
}),
|
||||||
|
Label = e("TextLabel", {
|
||||||
|
Text = props.text,
|
||||||
|
BackgroundTransparency = 1,
|
||||||
|
FontFace = theme.Font.Thin,
|
||||||
|
TextSize = theme.TextSize.Small,
|
||||||
|
TextColor3 = tagColor,
|
||||||
|
TextXAlignment = Enum.TextXAlignment.Center,
|
||||||
|
TextTransparency = props.transparency,
|
||||||
|
Size = UDim2.new(0, 0, 1, 0),
|
||||||
|
AutomaticSize = Enum.AutomaticSize.X,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
local Expansion = Roact.Component:extend("Expansion")
|
local Expansion = Roact.Component:extend("Expansion")
|
||||||
|
|
||||||
function Expansion:render()
|
function Expansion:render()
|
||||||
|
|
@ -247,30 +281,31 @@ function DomLabel:render()
|
||||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||||
Padding = UDim.new(0, 4),
|
Padding = UDim.new(0, 4),
|
||||||
}),
|
}),
|
||||||
Edits = if props.changeInfo and props.changeInfo.edits
|
LinesTag = if props.changeInfo and props.changeInfo.lineChanges
|
||||||
then e("TextLabel", {
|
then e(ChangeTag, {
|
||||||
Text = props.changeInfo.edits .. if props.changeInfo.failed then "," else "",
|
text = (if props.changeInfo.isWhitespaceOnly then "Whitespace " else "Lines ")
|
||||||
BackgroundTransparency = 1,
|
.. (if props.changeInfo.lineChanges >= 10000 then "100+" else props.changeInfo.lineChanges),
|
||||||
FontFace = theme.Font.Thin,
|
color = if props.changeInfo.isWhitespaceOnly
|
||||||
TextSize = theme.TextSize.Body,
|
then theme.Diff.WhitespaceOnly
|
||||||
TextColor3 = theme.SubTextColor,
|
else theme.Diff.Changes,
|
||||||
TextTransparency = props.transparency,
|
transparency = props.transparency,
|
||||||
Size = UDim2.new(0, 0, 0, theme.TextSize.Body),
|
layoutOrder = 1,
|
||||||
AutomaticSize = Enum.AutomaticSize.X,
|
})
|
||||||
LayoutOrder = 2,
|
else nil,
|
||||||
|
PropsTag = if props.changeInfo and props.changeInfo.propChanges
|
||||||
|
then e(ChangeTag, {
|
||||||
|
text = "Props " .. props.changeInfo.propChanges,
|
||||||
|
color = theme.Diff.Changes or theme.Diff.Background.Edit,
|
||||||
|
transparency = props.transparency,
|
||||||
|
layoutOrder = 2,
|
||||||
})
|
})
|
||||||
else nil,
|
else nil,
|
||||||
Failed = if props.changeInfo and props.changeInfo.failed
|
Failed = if props.changeInfo and props.changeInfo.failed
|
||||||
then e("TextLabel", {
|
then e(ChangeTag, {
|
||||||
Text = props.changeInfo.failed,
|
text = "Failed " .. props.changeInfo.failed,
|
||||||
BackgroundTransparency = 1,
|
color = theme.Diff.Warning,
|
||||||
FontFace = theme.Font.Thin,
|
transparency = props.transparency,
|
||||||
TextSize = theme.TextSize.Body,
|
layoutOrder = 3,
|
||||||
TextColor3 = theme.Diff.Warning,
|
|
||||||
TextTransparency = props.transparency,
|
|
||||||
Size = UDim2.new(0, 0, 0, theme.TextSize.Body),
|
|
||||||
AutomaticSize = Enum.AutomaticSize.X,
|
|
||||||
LayoutOrder = 6,
|
|
||||||
})
|
})
|
||||||
else nil,
|
else nil,
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,8 @@ function StudioProvider:updateTheme()
|
||||||
|
|
||||||
Row = studioTheme:GetColor(Enum.StudioStyleGuideColor.BrightText),
|
Row = studioTheme:GetColor(Enum.StudioStyleGuideColor.BrightText),
|
||||||
Warning = studioTheme:GetColor(Enum.StudioStyleGuideColor.WarningText),
|
Warning = studioTheme:GetColor(Enum.StudioStyleGuideColor.WarningText),
|
||||||
|
WhitespaceOnly = if isDark then Color3.fromRGB(140, 140, 140) else Color3.fromRGB(110, 110, 110),
|
||||||
|
Changes = if isDark then Color3.fromRGB(100, 140, 220) else Color3.fromRGB(40, 100, 180),
|
||||||
|
|
||||||
Background = {
|
Background = {
|
||||||
-- Studio doesn't have good colors since their diffs use backgrounds, not text
|
-- Studio doesn't have good colors since their diffs use backgrounds, not text
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ local Log = require(Packages.Log)
|
||||||
|
|
||||||
local Timer = require(Plugin.Timer)
|
local Timer = require(Plugin.Timer)
|
||||||
local Types = require(Plugin.Types)
|
local Types = require(Plugin.Types)
|
||||||
|
local WhitespaceUtil = require(Plugin.WhitespaceUtil)
|
||||||
local decodeValue = require(Plugin.Reconciler.decodeValue)
|
local decodeValue = require(Plugin.Reconciler.decodeValue)
|
||||||
local getProperty = require(Plugin.Reconciler.getProperty)
|
local getProperty = require(Plugin.Reconciler.getProperty)
|
||||||
|
|
||||||
|
|
@ -237,13 +238,16 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
|
||||||
|
|
||||||
-- Gather detail text
|
-- Gather detail text
|
||||||
local changeList, changeInfo = nil, nil
|
local changeList, changeInfo = nil, nil
|
||||||
|
local totalLineChanges = 0
|
||||||
|
local whitespaceLineChanges = 0
|
||||||
|
local hasSourceChange = false
|
||||||
if next(change.changedProperties) or change.changedName then
|
if next(change.changedProperties) or change.changedName then
|
||||||
changeList = {}
|
changeList = {}
|
||||||
|
|
||||||
local changeIndex = 0
|
local changeIndex = 0
|
||||||
local function addProp(prop: string, current: any?, incoming: any?, metadata: any?)
|
local function addProp(prop: string, current: any?, incoming: any?)
|
||||||
changeIndex += 1
|
changeIndex += 1
|
||||||
changeList[changeIndex] = { prop, current, incoming, metadata }
|
changeList[changeIndex] = { prop, current, incoming }
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Gather the changes
|
-- Gather the changes
|
||||||
|
|
@ -256,6 +260,12 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
|
||||||
local incomingSuccess, incomingValue = decodeValue(incoming, instanceMap)
|
local incomingSuccess, incomingValue = decodeValue(incoming, instanceMap)
|
||||||
local currentSuccess, currentValue = getProperty(instance, prop)
|
local currentSuccess, currentValue = getProperty(instance, prop)
|
||||||
|
|
||||||
|
-- Check if this is a Source property - count line differences
|
||||||
|
if prop == "Source" and currentSuccess and incomingSuccess then
|
||||||
|
hasSourceChange = true
|
||||||
|
totalLineChanges, whitespaceLineChanges = WhitespaceUtil.CountLineDifferences(currentValue, incomingValue)
|
||||||
|
end
|
||||||
|
|
||||||
addProp(
|
addProp(
|
||||||
prop,
|
prop,
|
||||||
if currentSuccess then currentValue else "[Error]",
|
if currentSuccess then currentValue else "[Error]",
|
||||||
|
|
@ -263,8 +273,15 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Count non-Source property changes
|
||||||
|
local propCount = changeIndex - (if hasSourceChange then 1 else 0)
|
||||||
|
|
||||||
changeInfo = {
|
changeInfo = {
|
||||||
edits = changeIndex,
|
-- Line changes for Source (nil if no Source change)
|
||||||
|
lineChanges = if hasSourceChange and totalLineChanges > 0 then totalLineChanges else nil,
|
||||||
|
isWhitespaceOnly = hasSourceChange and totalLineChanges > 0 and totalLineChanges == whitespaceLineChanges,
|
||||||
|
-- Property changes (non-Source: Name, Attributes, etc.)
|
||||||
|
propChanges = if propCount > 0 then propCount else nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Sort changes and add header
|
-- Sort changes and add header
|
||||||
|
|
|
||||||
50
plugin/src/WhitespaceUtil.lua
Normal file
50
plugin/src/WhitespaceUtil.lua
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
--[[
|
||||||
|
Utility for detecting whitespace-only changes in source code.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local WhitespaceUtil = {}
|
||||||
|
|
||||||
|
local function SplitLines(str: string): { string }
|
||||||
|
local lines = {}
|
||||||
|
for line in string.gmatch(str .. "\n", "([^\n]*)\n") do
|
||||||
|
table.insert(lines, line)
|
||||||
|
end
|
||||||
|
return lines
|
||||||
|
end
|
||||||
|
|
||||||
|
local function NormalizeLine(line: string): string
|
||||||
|
return string.gsub(string.gsub(line, "\r+$", ""), "[ \t]+$", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Counts lines that differ between two strings (capped at 100)
|
||||||
|
-- Returns: totalDiff, whitespaceDiff (lines that only differ in whitespace)
|
||||||
|
-- Returns 10000, 10000 if exceeds 100 (frontend displays as "100+")
|
||||||
|
function WhitespaceUtil.CountLineDifferences(current: string, incoming: string): (number, number)
|
||||||
|
if type(current) ~= "string" or type(incoming) ~= "string" then
|
||||||
|
return 0, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local currentLines = SplitLines(current)
|
||||||
|
local incomingLines = SplitLines(incoming)
|
||||||
|
local maxLines = math.max(#currentLines, #incomingLines)
|
||||||
|
|
||||||
|
local totalDiff, whitespaceDiff = 0, 0
|
||||||
|
for i = 1, maxLines do
|
||||||
|
local currentLine = currentLines[i] or ""
|
||||||
|
local incomingLine = incomingLines[i] or ""
|
||||||
|
|
||||||
|
if currentLine ~= incomingLine then
|
||||||
|
totalDiff += 1
|
||||||
|
if NormalizeLine(currentLine) == NormalizeLine(incomingLine) then
|
||||||
|
whitespaceDiff += 1
|
||||||
|
end
|
||||||
|
if totalDiff > 100 then
|
||||||
|
return 10000, 10000
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return totalDiff, whitespaceDiff
|
||||||
|
end
|
||||||
|
|
||||||
|
return WhitespaceUtil
|
||||||
Loading…
Add table
Add a link
Reference in a new issue