Skip to content

Commit 4b29828

Browse files
committed
feat: option to efficiently use horizontal space
1 parent dc8adec commit 4b29828

2 files changed

Lines changed: 59 additions & 20 deletions

File tree

pretty/formatter.test.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { assertEquals } from "@std/assert/equals";
55
import { assertMatch } from "@std/assert/match";
66
import { assertStringIncludes } from "@std/assert/string-includes";
77
import {
8-
type CategoryColorMap,
9-
getPrettyFormatter,
10-
prettyFormatter,
8+
type CategoryColorMap,
9+
getPrettyFormatter,
10+
prettyFormatter,
1111
} from "./formatter.ts";
1212

1313
const test = suite(import.meta);
@@ -829,3 +829,30 @@ test("properties set to true", () => {
829829
"Deno" in globalThis ? 'bar: "baz"' : "bar: 'baz'",
830830
);
831831
});
832+
833+
test("newLine set to true", () => {
834+
const formatter = getPrettyFormatter({
835+
properties: true,
836+
colors: false,
837+
messageNewLine: true,
838+
inspectOptions: { colors: false },
839+
});
840+
841+
const record = createLogRecord("info", ["test"], ["FooBar"], Date.now(), {
842+
foo: "bar",
843+
bar: "baz",
844+
});
845+
const result = formatter(record);
846+
console.error(result)
847+
// Should contain multiple lines due to wrapping
848+
const lines = result.split("\n");
849+
assertEquals(lines.length, 5); // Normal log line + 1 for horizontal space + formatted properties + newline
850+
assertEquals(
851+
lines[2].trim(),
852+
"Deno" in globalThis ? 'foo: "bar"' : "foo: 'bar'",
853+
);
854+
assertEquals(
855+
lines[3].trim(),
856+
"Deno" in globalThis ? 'bar: "baz"' : "bar: 'baz'",
857+
);
858+
});

pretty/formatter.ts

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
import { inspect, type InspectOptions } from "#util";
12
import {
2-
getLogLevels,
3-
type LogLevel,
4-
type LogRecord,
5-
type TextFormatter,
6-
type TextFormatterOptions,
3+
getLogLevels,
4+
type LogLevel,
5+
type LogRecord,
6+
type TextFormatter,
7+
type TextFormatterOptions,
78
} from "@logtape/logtape";
8-
import { inspect, type InspectOptions } from "#util";
99
import { getOptimalWordWrapWidth } from "./terminal.ts";
1010
import { truncateCategory, type TruncationStrategy } from "./truncate.ts";
1111
import { getDisplayWidth, stripAnsi } from "./wcwidth.ts";
@@ -476,7 +476,15 @@ export interface PrettyFormatterOptions
476476
* @default `"rgb(148,163,184)"` (light slate gray)
477477
*/
478478
readonly messageColor?: Color;
479-
479+
/**
480+
* Visual style applied to save some horizontal space
481+
*
482+
* Controls whether the message will start after the category, or whether
483+
* it will wrap below the categories, where the categories appear as a heading
484+
*
485+
* @default false
486+
*/
487+
readonly messageNewLine?: boolean;
480488
/**
481489
* Visual style applied to log message text.
482490
*
@@ -672,6 +680,7 @@ export function getPrettyFormatter(
672680
categoryTruncate = "middle",
673681
messageColor = "rgb(148,163,184)",
674682
messageStyle = "dim",
683+
messageNewLine = false,
675684
colors: useColors = true,
676685
align = true,
677686
inspectOptions = {},
@@ -822,6 +831,7 @@ export function getPrettyFormatter(
822831
let message = "";
823832
const messageColorCode = useColors ? colorToAnsi(messageColor) : "";
824833
const messageStyleCode = useColors ? styleToAnsi(messageStyle) : "";
834+
const messageStart = messageNewLine ? "\n" : "";
825835
const messagePrefix = useColors
826836
? `${messageStyleCode}${messageColorCode}`
827837
: "";
@@ -932,12 +942,14 @@ export function getPrettyFormatter(
932942
);
933943

934944
let result =
935-
`${formattedTimestamp}${formattedIcon} ${paddedLevel} ${paddedCategory} ${formattedMessage}`;
936-
const indentWidth = getDisplayWidth(
937-
stripAnsi(
938-
`${formattedTimestamp}${formattedIcon} ${paddedLevel} ${paddedCategory} `,
939-
),
940-
);
945+
`${formattedTimestamp}${formattedIcon} ${paddedLevel} ${paddedCategory} ${messageStart}${formattedMessage}`;
946+
const indentWidth = !messageNewLine
947+
? getDisplayWidth(
948+
stripAnsi(
949+
`${formattedTimestamp}${formattedIcon} ${paddedLevel} ${paddedCategory} `,
950+
),
951+
)
952+
: 4;
941953

942954
// Apply word wrapping if enabled, or if there are multiline interpolated values
943955
if (wordWrapEnabled || message.includes("\n")) {
@@ -961,12 +973,12 @@ export function getPrettyFormatter(
961973
return result + "\n";
962974
} else {
963975
let result =
964-
`${formattedTimestamp}${formattedIcon} ${formattedLevel} ${formattedCategory} ${formattedMessage}`;
965-
const indentWidth = getDisplayWidth(
976+
`${formattedTimestamp}${formattedIcon} ${formattedLevel} ${formattedCategory} ${messageStart}${formattedMessage}`;
977+
const indentWidth = !messageNewLine ?getDisplayWidth(
966978
stripAnsi(
967979
`${formattedTimestamp}${formattedIcon} ${formattedLevel} ${formattedCategory} `,
968980
),
969-
);
981+
): 4;
970982

971983
// Apply word wrapping if enabled, or if there are multiline interpolated values
972984
if (wordWrapEnabled || message.includes("\n")) {
@@ -1002,7 +1014,7 @@ function formatProperties(
10021014
let result = "";
10031015
for (const prop in record.properties) {
10041016
const propValue = record.properties[prop];
1005-
const pad = indentWidth - getDisplayWidth(prop) - 2;
1017+
const pad = Math.max(6, indentWidth - getDisplayWidth(prop) - 2);
10061018
result += "\n" + wrapText(
10071019
`${" ".repeat(pad)}${useColors ? DIM : ""}${prop}:${
10081020
useColors ? RESET : ""

0 commit comments

Comments
 (0)