From 23ea10a6e7d021d7dfd365f54baae56170107601 Mon Sep 17 00:00:00 2001 From: David Gregory <2992938+DavidGregory084@users.noreply.github.com> Date: Sat, 8 Jun 2024 15:03:01 +0100 Subject: [PATCH] Don't layout an entire alternative before deciding whether it fits --- .../com/opencastsoftware/prettier4j/Doc.java | 53 ++++++------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/opencastsoftware/prettier4j/Doc.java b/src/main/java/com/opencastsoftware/prettier4j/Doc.java index 9b3657f..5a2168a 100644 --- a/src/main/java/com/opencastsoftware/prettier4j/Doc.java +++ b/src/main/java/com/opencastsoftware/prettier4j/Doc.java @@ -1662,38 +1662,6 @@ private static Entry entry(int indent, Doc margin, Doc doc) { return new Entry(indent, margin, doc); } - /** - * Inspects the remaining space on the current line and the entries in the - * current layout to see whether they fit onto the current line. - *

- * It's only necessary to inspect entries up to the next line break. - * - * @param remaining the remaining space on the current line. - * @param entries the entries we'd like to fit onto this line - * @return true if we can fit all {@link Doc.Text entries} up to the - * next line break into the remaining characters of the current line. - */ - static boolean fits(int remaining, Queue entries) { - if (remaining < 0) - return false; - - for (Entry entry : entries) { - Doc entryDoc = entry.doc(); - - // layout reduces Doc to Text, LineOr, Escape and Reset - if (entryDoc instanceof Text) { - Text textDoc = (Text) entryDoc; - remaining -= textDoc.text().length(); - if (remaining < 0) - return false; - } else if (entryDoc instanceof LineOr) { - return true; - } // No need to handle Escape or Reset as they are effectively zero-length - } - - return true; - } - /** * Choose between two layouts at the current rendering width, indentation level * and line position, choosing the {@code left} document if it fits and the @@ -1708,15 +1676,24 @@ static boolean fits(int remaining, Queue entries) { * @return the entries of the chosen layout. */ private static Queue chooseLayout(Doc left, Doc right, RenderOptions options, Doc margin, int indent, int position) { - Queue leftEntries = layout(left, options, margin, indent, position); + Deque inQueue = new ArrayDeque<>(); + Queue outQueue = new ArrayDeque<>(); - int remaining = options.lineWidth() - position; + inQueue.add(entry(indent, margin, left)); - if (fits(remaining, leftEntries)) { - return leftEntries; - } else { - return layout(right, options, margin, indent, position); + while (!inQueue.isEmpty()) { + Entry topEntry = inQueue.removeFirst(); + position = layoutEntry(options, inQueue, outQueue, topEntry, position); + + int remaining = options.lineWidth() - position; + + if (remaining < 0) { + // The new entry doesn't fit, so use the other layout + return layout(right, options, margin, indent, position); + } } + + return outQueue; } /**