Conversation
📝 WalkthroughWalkthroughRemoves tokenizer sources and PBX wiring, simplifies theme persistence to isDarkMode-only, updates SyntaxHighlighter and CodeEditor async highlighting flow, refactors formatter and view-model wiring, adjusts UI/layout, and updates tests and Xcode build settings. ChangesTokenizer removal and theme/editor architecture refactoring
Sequence Diagram(s)sequenceDiagram
participant CodeEditorView
participant NSTextView
participant SyntaxHighlighter
CodeEditorView->>NSTextView: synchronize bound text and capture selection
CodeEditorView->>NSTextView: update theme colors & font
CodeEditorView->>SyntaxHighlighter: highlight(attributedString, theme)
SyntaxHighlighter-->>CodeEditorView: highlighted attributes
CodeEditorView->>NSTextView: apply attributes and restore selection
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
Note Docstrings generation - SUCCESS |
Docstrings generation was requested by @csprasad. The following files were modified: * `DevLint/DevLint/Components/CodeEditorView.swift` * `DevLint/DevLint/Core/ThemeManager.swift` * `DevLint/DevLint/SyntaxHighlighting/SyntaxHighlighter.swift` * `DevLint/DevLint/Utilities/Formatters/CodeFormatter.swift` * `DevLint/DevLint/Utilities/Formatters/SwiftFormatAdapter.swift` * `DevLint/DevLint/ViewModels/CodeEditorViewModel.swift` These files were ignored: * `DevLint/DevLintTests/DevLintTests.swift` * `DevLint/DevLintTests/TokenizerTests.swift` These file types are not supported: * `DevLint/DevLint.xcodeproj/project.pbxproj`
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
DevLint/DevLint/Core/ThemeManager.swift (1)
84-87:⚠️ Potential issue | 🟠 Major | ⚡ Quick winApply the persisted appearance during initialization.
init()restorescurrentThemefromisDarkMode, but it never applies the matchingNSApp.appearance. On launch with a persisted dark-mode preference, the editor theme becomes dark while the app chrome can stay in the default Aqua appearance until the user toggles the setting again.Suggested fix
init() { self.currentTheme = availableThemes[0] updateThemeForDarkMode() + applyAppearance() }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@DevLint/DevLint/Core/ThemeManager.swift` around lines 84 - 87, The initializer sets currentTheme from availableThemes and calls updateThemeForDarkMode() but never applies the persisted app appearance; after restoring currentTheme in init(), set NSApp.appearance according to the persisted dark-mode flag (e.g., if isDarkMode or currentTheme indicates dark, assign NSApp.appearance = NSAppearance(named: .darkAqua), otherwise set to nil or NSAppearance(named: .aqua)) or call the existing theme-application routine that applies window chrome; update init() to explicitly apply NSApp.appearance so the app chrome matches currentTheme on launch.DevLint/DevLint/Components/CodeEditorView.swift (1)
114-120:⚠️ Potential issue | 🟠 Major | ⚡ Quick winApply all editor colors/fonts unconditionally when the theme changes.
This guard keys the whole update off
backgroundColoronly. If the new theme shares the same background as the currentNSTextViewstate,textColor,insertionPointColor, andfontnever refresh. That also leaves the initial "Default" theme partially unapplied when the view starts with the system white background.Suggested fix
private func updateThemeIfNeeded(for textView: NSTextView) { - if textView.backgroundColor != themeManager.currentTheme.backgroundColor { - textView.backgroundColor = themeManager.currentTheme.backgroundColor - textView.textColor = themeManager.currentTheme.primaryColor - textView.insertionPointColor = themeManager.currentTheme.primaryColor - textView.font = NSFont.monospacedSystemFont(ofSize: 14, weight: .regular) - } + textView.backgroundColor = themeManager.currentTheme.backgroundColor + textView.textColor = themeManager.currentTheme.primaryColor + textView.insertionPointColor = themeManager.currentTheme.primaryColor + textView.font = NSFont.monospacedSystemFont(ofSize: 14, weight: .regular) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@DevLint/DevLint/Components/CodeEditorView.swift` around lines 114 - 120, The updateThemeIfNeeded(for:) method currently gates all updates on textView.backgroundColor matching the theme, causing textColor/insertionPointColor/font to not refresh; change it so the editor colors and font are applied whenever the theme changes — either by removing the backgroundColor conditional and always assigning textView.backgroundColor, textView.textColor, textView.insertionPointColor, and textView.font from themeManager.currentTheme, or by tracking the lastAppliedTheme (e.g., a stored property) and comparing that to themeManager.currentTheme to decide when to update; ensure you reference updateThemeIfNeeded(for:), themeManager.currentTheme.backgroundColor/primaryColor, and the textView property assignments when making the fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@DevLint/DevLintTests/TokenizerTests.swift`:
- Around line 13-120: The tests still reference the removed Tokenizer API
(constructing Tokenizer and using Token.TokenType via assertTokenization), so
either delete this test file or rewrite it to exercise the new
syntax-highlighting surface; specifically remove usages of Tokenizer,
Token.TokenType and assertTokenization as written, and replace them with calls
to the new highlighter interface (or unregister
DevLint/DevLintTests/TokenizerTests.swift from the DevLintTests target) so the
test bundle can compile.
---
Outside diff comments:
In `@DevLint/DevLint/Components/CodeEditorView.swift`:
- Around line 114-120: The updateThemeIfNeeded(for:) method currently gates all
updates on textView.backgroundColor matching the theme, causing
textColor/insertionPointColor/font to not refresh; change it so the editor
colors and font are applied whenever the theme changes — either by removing the
backgroundColor conditional and always assigning textView.backgroundColor,
textView.textColor, textView.insertionPointColor, and textView.font from
themeManager.currentTheme, or by tracking the lastAppliedTheme (e.g., a stored
property) and comparing that to themeManager.currentTheme to decide when to
update; ensure you reference updateThemeIfNeeded(for:),
themeManager.currentTheme.backgroundColor/primaryColor, and the textView
property assignments when making the fix.
In `@DevLint/DevLint/Core/ThemeManager.swift`:
- Around line 84-87: The initializer sets currentTheme from availableThemes and
calls updateThemeForDarkMode() but never applies the persisted app appearance;
after restoring currentTheme in init(), set NSApp.appearance according to the
persisted dark-mode flag (e.g., if isDarkMode or currentTheme indicates dark,
assign NSApp.appearance = NSAppearance(named: .darkAqua), otherwise set to nil
or NSAppearance(named: .aqua)) or call the existing theme-application routine
that applies window chrome; update init() to explicitly apply NSApp.appearance
so the app chrome matches currentTheme on launch.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8a1ebb05-5431-43e2-a041-c9813f46c041
📒 Files selected for processing (22)
DevLint/DevLint.xcodeproj/project.pbxprojDevLint/DevLint/App/DevLintApp.swiftDevLint/DevLint/Components/CodeEditorView.swiftDevLint/DevLint/Core/ThemeManager.swiftDevLint/DevLint/Models/CodeEditorModel.swiftDevLint/DevLint/Models/ThemeModel.swiftDevLint/DevLint/SyntaxHighlighting/SyntaxHighlighter.swiftDevLint/DevLint/SyntaxHighlighting/Tokenizer/LanguageRules.swiftDevLint/DevLint/SyntaxHighlighting/Tokenizer/SwiftLanguageRules.swiftDevLint/DevLint/SyntaxHighlighting/Tokenizer/Token.swiftDevLint/DevLint/SyntaxHighlighting/Tokenizer/Tokenizer.swiftDevLint/DevLint/Utilities/Extensions/Extensions.swiftDevLint/DevLint/Utilities/Formatters/CodeFormatter.swiftDevLint/DevLint/Utilities/Formatters/SwiftFormatAdapter.swiftDevLint/DevLint/ViewModels/CodeEditorViewModel.swiftDevLint/DevLint/Views/CodeEditorContainer.swiftDevLint/DevLint/Views/ContentView.swiftDevLint/DevLint/Views/CustomToolbar.swiftDevLint/DevLint/Views/EditorSectionView.swiftDevLint/DevLint/Views/ToolbarButton.swiftDevLint/DevLintTests/DevLintTests.swiftDevLint/DevLintTests/TokenizerTests.swift
💤 Files with no reviewable changes (8)
- DevLint/DevLint/SyntaxHighlighting/Tokenizer/Token.swift
- DevLint/DevLint/Views/ContentView.swift
- DevLint/DevLintTests/DevLintTests.swift
- DevLint/DevLint/Models/ThemeModel.swift
- DevLint/DevLint/SyntaxHighlighting/Tokenizer/LanguageRules.swift
- DevLint/DevLint/Models/CodeEditorModel.swift
- DevLint/DevLint/SyntaxHighlighting/Tokenizer/SwiftLanguageRules.swift
- DevLint/DevLint/SyntaxHighlighting/Tokenizer/Tokenizer.swift
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@DevLint/DevLint/Components/CodeEditorView.swift`:
- Around line 124-125: The doc comment above the method that updates a text
view's colors (the triple-slash comment describing "Updates the given text
view's colors and font..." and the "- Parameter textView: ..." line) has 8
spaces of indentation on the second line; change that line to match the standard
4-space indentation used by other doc comments in CodeEditorView.swift so the
comment block is consistently indented with the rest of the file.
- Line 71: Remove the leftover debug print statement that logs
themeManager.currentTheme.name (the line "print(themeManager.currentTheme.name +
\"theme on text bg\")") from CodeEditorView (where the view is created); simply
delete that print call (or replace it with a conditional debug-only logger if
needed) so it no longer executes on every view creation.
In `@DevLint/DevLint/ViewModels/CodeEditorViewModel.swift`:
- Around line 49-52: The clear() method currently resets inputCode and
formattedCode but leaves lineNumbers stale; update clear() in
CodeEditorViewModel to also reset/recompute the gutter by clearing or
regenerating lineNumbers (e.g., set lineNumbers = [] or call
updateLineNumbers()) so the editor shows zero lines immediately after clear;
reference the clear() function and the lineNumbers property and
updateLineNumbers() helper when making the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 67813209-9494-4785-a218-b17264dc2f30
📒 Files selected for processing (6)
DevLint/DevLint/Components/CodeEditorView.swiftDevLint/DevLint/Core/ThemeManager.swiftDevLint/DevLint/SyntaxHighlighting/SyntaxHighlighter.swiftDevLint/DevLint/Utilities/Formatters/CodeFormatter.swiftDevLint/DevLint/Utilities/Formatters/SwiftFormatAdapter.swiftDevLint/DevLint/ViewModels/CodeEditorViewModel.swift
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
DevLint/DevLint/Core/ThemeManager.swift (2)
84-87:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winApply the persisted appearance during initialization.
When
isDarkModeis alreadytrueinAppStorage,init()switchescurrentThemeto"Dark"but never callsapplyAppearance(), so the editor theme and the app chrome can start out mismatched until the toggle changes again. CallapplyAppearance()once after restoring the initial theme.Suggested fix
init() { self.currentTheme = availableThemes[0] updateThemeForDarkMode() + applyAppearance() }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@DevLint/DevLint/Core/ThemeManager.swift` around lines 84 - 87, The initializer sets self.currentTheme from availableThemes[0] and calls updateThemeForDarkMode() but doesn't apply the restored appearance, so when isDarkMode (AppStorage) is true the UI can be out of sync; after updateThemeForDarkMode() in init() call applyAppearance() to ensure the editor theme and app chrome are applied immediately (referencing init(), currentTheme, availableThemes, updateThemeForDarkMode(), applyAppearance(), and isDarkMode).
13-17:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPersisting only
isDarkModeregresses theme restoration.
CustomToolbarstill lets users pick"Solarized"via$themeManager.currentTheme, but this manager now restores state fromisDarkModealone, so every non-Default/Darkselection is lost on relaunch. If this PR intentionally collapses themes down to light/dark only, the picker should be constrained to match; otherwise the selected theme name still needs persistence.Suggested fix
class ThemeManager: ObservableObject { `@Published` var currentTheme: ThemeModel + `@AppStorage`("selectedThemeName") private var selectedThemeName: String = "Default" `@AppStorage`("isDarkMode") var isDarkMode: Bool = false { didSet { updateThemeForDarkMode() applyAppearance() } @@ init() { self.currentTheme = availableThemes[0] - updateThemeForDarkMode() + setTheme(name: selectedThemeName) + applyAppearance() } @@ func setTheme(name: String) { if let newTheme = availableThemes.first(where: { $0.name == name }) { currentTheme = newTheme + selectedThemeName = name } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@DevLint/DevLint/Core/ThemeManager.swift` around lines 13 - 17, Theme restoration regresses because ThemeManager now only persists `@AppStorage`("isDarkMode") isDarkMode and ignores the selected theme used by CustomToolbar via $themeManager.currentTheme; restore the selected theme by persisting the theme identifier (e.g., add `@AppStorage`("currentThemeName") var currentThemeName: String? or similar) and update ThemeManager's init/restore path to set currentTheme from that stored name (or, if the design intentionally collapses to light/dark, restrict the CustomToolbar picker to only Default/Dark and remove references to non-binary themes); update updateThemeForDarkMode/applyAppearance to respect the persisted currentThemeName when present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@DevLint/DevLint/Core/ThemeManager.swift`:
- Around line 84-87: The initializer sets self.currentTheme from
availableThemes[0] and calls updateThemeForDarkMode() but doesn't apply the
restored appearance, so when isDarkMode (AppStorage) is true the UI can be out
of sync; after updateThemeForDarkMode() in init() call applyAppearance() to
ensure the editor theme and app chrome are applied immediately (referencing
init(), currentTheme, availableThemes, updateThemeForDarkMode(),
applyAppearance(), and isDarkMode).
- Around line 13-17: Theme restoration regresses because ThemeManager now only
persists `@AppStorage`("isDarkMode") isDarkMode and ignores the selected theme
used by CustomToolbar via $themeManager.currentTheme; restore the selected theme
by persisting the theme identifier (e.g., add `@AppStorage`("currentThemeName")
var currentThemeName: String? or similar) and update ThemeManager's init/restore
path to set currentTheme from that stored name (or, if the design intentionally
collapses to light/dark, restrict the CustomToolbar picker to only Default/Dark
and remove references to non-binary themes); update
updateThemeForDarkMode/applyAppearance to respect the persisted currentThemeName
when present.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a8cb9632-656d-4e69-aa05-5a34a57f2add
📒 Files selected for processing (7)
DevLint/DevLint.xcodeproj/project.pbxprojDevLint/DevLint/Components/CodeEditorView.swiftDevLint/DevLint/Core/ThemeManager.swiftDevLint/DevLint/Models/ThemeModel.swiftDevLint/DevLint/Utilities/Formatters/CodeFormatter.swiftDevLint/DevLint/Views/CodeOutputView.swiftDevLint/DevLintTests/TokenizerTests.swift
💤 Files with no reviewable changes (5)
- DevLint/DevLint/Models/ThemeModel.swift
- DevLint/DevLint/Utilities/Formatters/CodeFormatter.swift
- DevLint/DevLint/Components/CodeEditorView.swift
- DevLint/DevLintTests/TokenizerTests.swift
- DevLint/DevLint.xcodeproj/project.pbxproj
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@DevLint/DevLint/Components/CodeEditorView.swift`:
- Around line 120-126: In updateThemeIfNeeded(for:) replace the hardcoded
NSFont.monospacedSystemFont(ofSize:14, weight:.regular) with the theme's
configured font so the editor stays in sync with ThemeManager; use
themeManager.currentTheme.font (with a safe fallback to a sensible default font
if that property is nil) to set textView.font, leaving the backgroundColor,
textColor and insertionPointColor assignments unchanged.
In `@DevLint/DevLint/Core/ThemeManager.swift`:
- Around line 85-89: The initializer is overwriting persisted theme because
updateThemeForDarkMode() mutates selectedThemeName before setTheme(name:)
restores it, and the toolbar picker binds currentTheme directly so changes never
call setTheme(name:) to persist; fix by moving persistence onto currentTheme
(add a didSet on currentTheme to call setTheme(name:) or persist the
selectedThemeName) so any change to currentTheme is saved, and change
updateThemeForDarkMode() to apply a dark-mode fallback without mutating the
stored selectedThemeName (only adjust currentTheme for UI presentation). Also
update CustomToolbar to bind the picker to currentTheme as before but rely on
currentTheme's didSet to persist rather than calling setTheme from the view.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8dbd90e5-e374-42a7-ac63-aa124bb43175
📒 Files selected for processing (4)
DevLint/DevLint/Components/CodeEditorView.swiftDevLint/DevLint/Core/ThemeManager.swiftDevLint/DevLint/Utilities/Formatters/CodeFormatter.swiftDevLint/DevLint/ViewModels/CodeEditorViewModel.swift
| /// Updates the given text view's colors and font when its background color differs from the current theme. | ||
| /// - Parameter textView: The `NSTextView` whose background color, text color, insertion point color, and font will be synchronized to the current theme if they are out of date. | ||
| private func updateThemeIfNeeded(for textView: NSTextView) { | ||
| textView.backgroundColor = themeManager.currentTheme.backgroundColor | ||
| textView.textColor = themeManager.currentTheme.primaryColor | ||
| textView.insertionPointColor = themeManager.currentTheme.primaryColor | ||
| textView.font = NSFont.monospacedSystemFont(ofSize: 14, weight: .regular) |
There was a problem hiding this comment.
Use the theme font here instead of hardcoding 14pt.
Line 126 ignores themeManager.currentTheme.font, so this method does not actually keep the editor font in sync with the active theme even though ThemeManager.swift stores a font per theme and this method’s contract says it does.
Suggested fix
- textView.font = NSFont.monospacedSystemFont(ofSize: 14, weight: .regular)
+ textView.font = themeManager.currentTheme.font📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /// Updates the given text view's colors and font when its background color differs from the current theme. | |
| /// - Parameter textView: The `NSTextView` whose background color, text color, insertion point color, and font will be synchronized to the current theme if they are out of date. | |
| private func updateThemeIfNeeded(for textView: NSTextView) { | |
| textView.backgroundColor = themeManager.currentTheme.backgroundColor | |
| textView.textColor = themeManager.currentTheme.primaryColor | |
| textView.insertionPointColor = themeManager.currentTheme.primaryColor | |
| textView.font = NSFont.monospacedSystemFont(ofSize: 14, weight: .regular) | |
| /// Updates the given text view's colors and font when its background color differs from the current theme. | |
| /// - Parameter textView: The `NSTextView` whose background color, text color, insertion point color, and font will be synchronized to the current theme if they are out of date. | |
| private func updateThemeIfNeeded(for textView: NSTextView) { | |
| textView.backgroundColor = themeManager.currentTheme.backgroundColor | |
| textView.textColor = themeManager.currentTheme.primaryColor | |
| textView.insertionPointColor = themeManager.currentTheme.primaryColor | |
| textView.font = themeManager.currentTheme.font |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@DevLint/DevLint/Components/CodeEditorView.swift` around lines 120 - 126, In
updateThemeIfNeeded(for:) replace the hardcoded
NSFont.monospacedSystemFont(ofSize:14, weight:.regular) with the theme's
configured font so the editor stays in sync with ThemeManager; use
themeManager.currentTheme.font (with a safe fallback to a sensible default font
if that property is nil) to set textView.font, leaving the backgroundColor,
textColor and insertionPointColor assignments unchanged.
Summary by CodeRabbit
Refactor
Style
Performance
Tests