From ae65660b6b2ed0645f3d9584cbeca856ba8defc6 Mon Sep 17 00:00:00 2001 From: Gerard Porto Date: Mon, 31 Aug 2026 09:27:21 +0200 Subject: [PATCH] Add configurable line number font --- .../Controller/TextViewController.swift | 3 +++ .../SourceEditorConfiguration+Appearance.swift | 9 ++++++++- .../Controller/TextViewControllerTests.swift | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Sources/CodeEditSourceEditor/Controller/TextViewController.swift b/Sources/CodeEditSourceEditor/Controller/TextViewController.swift index fb95c81c1..672708519 100644 --- a/Sources/CodeEditSourceEditor/Controller/TextViewController.swift +++ b/Sources/CodeEditSourceEditor/Controller/TextViewController.swift @@ -108,6 +108,9 @@ public class TextViewController: NSViewController { /// The font to use in the `textView` public var font: NSFont { configuration.appearance.font } + /// The optional font used for line numbers. When `nil`, the editor derives one from ``font``. + public var lineNumberFont: NSFont? { configuration.appearance.lineNumberFont } + /// The ``EditorTheme`` used for highlighting. public var theme: EditorTheme { configuration.appearance.theme } diff --git a/Sources/CodeEditSourceEditor/SourceEditorConfiguration/SourceEditorConfiguration+Appearance.swift b/Sources/CodeEditSourceEditor/SourceEditorConfiguration/SourceEditorConfiguration+Appearance.swift index 6ca03f2a7..399c2bfeb 100644 --- a/Sources/CodeEditSourceEditor/SourceEditorConfiguration/SourceEditorConfiguration+Appearance.swift +++ b/Sources/CodeEditSourceEditor/SourceEditorConfiguration/SourceEditorConfiguration+Appearance.swift @@ -19,6 +19,9 @@ extension SourceEditorConfiguration { /// The default font. public var font: NSFont + /// An optional font for line numbers. When `nil`, a font derived from ``font`` is used. + public var lineNumberFont: NSFont? + /// The line height multiplier (e.g. `1.2`). public var lineHeightMultiple: Double @@ -45,6 +48,7 @@ extension SourceEditorConfiguration { /// - useThemeBackground: Determines whether the editor uses the theme's background color, or a transparent /// background color. /// - font: The default font. + /// - lineNumberFont: An optional font for line numbers. Defaults to a font derived from `font`. /// - lineHeightMultiple: The line height multiplier (e.g. `1.2`). /// - letterSpacing: The amount of space to use between letters, as a percent. Eg: `1.0` = no space, `1.5` /// = 1/2 of a character's width between characters, etc. Defaults to `1.0`. @@ -57,6 +61,7 @@ extension SourceEditorConfiguration { theme: EditorTheme, useThemeBackground: Bool = true, font: NSFont, + lineNumberFont: NSFont? = nil, lineHeightMultiple: Double = 1.2, letterSpacing: Double = 1.0, wrapLines: Bool, @@ -67,6 +72,7 @@ extension SourceEditorConfiguration { self.theme = theme self.useThemeBackground = useThemeBackground self.font = font + self.lineNumberFont = lineNumberFont self.lineHeightMultiple = lineHeightMultiple self.letterSpacing = letterSpacing self.wrapLines = wrapLines @@ -86,10 +92,11 @@ extension SourceEditorConfiguration { if oldConfig?.font != font { controller.textView.font = font controller.textView.typingAttributes = controller.attributesFor(nil) - controller.gutterView.font = font.rulerFont needsHighlighterInvalidation = true } + controller.gutterView.font = lineNumberFont ?? font.rulerFont + if oldConfig?.theme != theme || oldConfig?.useThemeBackground != useThemeBackground { updateControllerNewTheme(controller: controller) needsHighlighterInvalidation = true diff --git a/Tests/CodeEditSourceEditorTests/Controller/TextViewControllerTests.swift b/Tests/CodeEditSourceEditorTests/Controller/TextViewControllerTests.swift index bef6615bd..d0ec0a942 100644 --- a/Tests/CodeEditSourceEditorTests/Controller/TextViewControllerTests.swift +++ b/Tests/CodeEditSourceEditorTests/Controller/TextViewControllerTests.swift @@ -235,6 +235,20 @@ final class TextViewControllerTests: XCTestCase { controller.configuration.appearance.letterSpacing = 1.0 } + func test_lineNumberFont() { + let defaultFont = controller.font.rulerFont + XCTAssertNil(controller.lineNumberFont) + XCTAssertEqual(controller.gutterView.font, defaultFont) + + let customFont = NSFont.monospacedSystemFont(ofSize: 17, weight: .bold) + controller.configuration.appearance.lineNumberFont = customFont + XCTAssertEqual(controller.lineNumberFont, customFont) + XCTAssertEqual(controller.gutterView.font, customFont) + + controller.configuration.appearance.lineNumberFont = nil + XCTAssertEqual(controller.gutterView.font, defaultFont) + } + // MARK: Bracket Highlights func test_bracketHighlights() throws {