From 5a3d2778250bd5a64985d3b13771dbc9ef5bd739 Mon Sep 17 00:00:00 2001 From: arikkfir Date: Mon, 24 Nov 2025 14:54:31 +0200 Subject: [PATCH] feat: Support fixed-length source code This change adds support for fixed-length source code field rendering, with smart-trimming that keeps the start & end section, with `...` replacing the part that gets removed. Configuration: ```go handler = console.NewHandler(os.Stdout, &console.HandlerOptions{ SourceLength: 20, }) ``` Examples (max-length 20): ``` Source: 1234567890 -> 10:00PM INF 1234567890 > Some log line Source: pkgA/pkgB/jack_the_knife.go:123 -> 10:00PM INF pkgA/pkg...fe.go:123 > Another log line Source: testing/superlogs.go:12 -> 10:00PM INF testing/...ogs.go:12 > Yet another log line ``` --- encoding.go | 23 ++++++++++++++++++++--- handler.go | 5 +++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/encoding.go b/encoding.go index 6088e65..8903479 100644 --- a/encoding.go +++ b/encoding.go @@ -5,6 +5,7 @@ import ( "log/slog" "path/filepath" "runtime" + "strings" "time" ) @@ -83,9 +84,25 @@ func (e encoder) writeSource(buf *buffer, pc uintptr, cwd string) { } } e.withColor(buf, e.opts.Theme.Source(), func() { - buf.AppendString(frame.File) - buf.AppendByte(':') - buf.AppendInt(int64(frame.Line)) + if e.opts.SourceLength > 0 { + source := fmt.Sprintf("%s:%d", frame.File, frame.Line) + if len(source) > e.opts.SourceLength { + charsThatFit := e.opts.SourceLength - 3 + frontChars := source[:charsThatFit/2] + if charsThatFit%2 == 1 { + charsThatFit = charsThatFit + 1 + } + rearChars := source[len(source)-charsThatFit/2:] + source = frontChars + "..." + rearChars + } else { + source = source + strings.Repeat(" ", e.opts.SourceLength-len(source)) + } + buf.AppendString(source) + } else { + buf.AppendString(frame.File) + buf.AppendByte(':') + buf.AppendInt(int64(frame.Line)) + } }) e.writeColoredString(buf, " > ", e.opts.Theme.AttrKey()) } diff --git a/handler.go b/handler.go index 82ce3ea..1edc314 100644 --- a/handler.go +++ b/handler.go @@ -33,6 +33,11 @@ type HandlerOptions struct { // Disable colorized output NoColor bool + // Enforce a fixed length for the source code field. If set, source code references longer than the field value + // will be trimmed but retain their starting & ending characters. If the source code is shorter than the set value, + // it is padded with spaces. + SourceLength int + // TimeFormat is the format used for time.DateTime TimeFormat string