Skip to content

Commit 775f9b4

Browse files
committed
Restore fixed cell wrapping for auto wrap
1 parent 0cd59ea commit 775f9b4

4 files changed

Lines changed: 3 additions & 323 deletions

File tree

src/MarkdownTableCore.cpp

Lines changed: 0 additions & 251 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ struct CodePointRange
6666
};
6767

6868
const std::size_t hardWrapCellWidth = 32;
69-
const std::size_t preferredWrappedColumnWidth = 18;
70-
const std::size_t minimumWrappedColumnWidth = 10;
7169

7270
std::size_t nextRowId(const Table &table);
7371

@@ -850,212 +848,6 @@ std::size_t wrapLongCells(Table &table, std::size_t originalTargetRow)
850848
return wrappedTargetRow;
851849
}
852850

853-
std::vector<std::size_t> naturalColumnWidths(const Table &table)
854-
{
855-
std::vector<std::size_t> widths(table.columns, 3);
856-
for (std::size_t rowIndex = 0; rowIndex < table.rows.size(); ++rowIndex)
857-
{
858-
const Row &row = table.rows[rowIndex];
859-
if (row.separator)
860-
continue;
861-
862-
for (std::size_t column = 0; column < table.columns; ++column)
863-
widths[column] = (std::max)(widths[column], displayWidth(row.cells[column]));
864-
}
865-
return widths;
866-
}
867-
868-
std::size_t formattedTableOverhead(const Table &table)
869-
{
870-
std::size_t overhead = table.leadingPipe ? 1 : 0;
871-
for (std::size_t column = 0; column < table.columns; ++column)
872-
{
873-
if (column > 0)
874-
overhead += 2;
875-
if (table.leadingPipe || column > 0)
876-
++overhead;
877-
if (table.trailingPipe && column + 1 == table.columns)
878-
overhead += 2;
879-
}
880-
return overhead;
881-
}
882-
883-
std::size_t widthSum(const std::vector<std::size_t> &widths)
884-
{
885-
std::size_t sum = 0;
886-
for (std::size_t i = 0; i < widths.size(); ++i)
887-
sum += widths[i];
888-
return sum;
889-
}
890-
891-
bool containsSpace(const std::string &value)
892-
{
893-
for (std::size_t i = 0; i < value.size(); ++i)
894-
{
895-
if (isSpace(static_cast<unsigned char>(value[i])))
896-
return true;
897-
}
898-
return false;
899-
}
900-
901-
std::vector<bool> textColumns(const Table &table)
902-
{
903-
std::vector<bool> result(table.columns, false);
904-
for (std::size_t rowIndex = 0; rowIndex < table.rows.size(); ++rowIndex)
905-
{
906-
const Row &row = table.rows[rowIndex];
907-
if (row.separator)
908-
continue;
909-
910-
for (std::size_t column = 0; column < table.columns; ++column)
911-
{
912-
if (displayWidth(row.cells[column]) > preferredWrappedColumnWidth && containsSpace(row.cells[column]))
913-
result[column] = true;
914-
}
915-
}
916-
return result;
917-
}
918-
919-
std::size_t largestShrinkableColumn(const std::vector<std::size_t> &widths, const std::vector<std::size_t> &minimums, const std::vector<bool> &allowed)
920-
{
921-
std::size_t best = static_cast<std::size_t>(-1);
922-
std::size_t bestWidth = 0;
923-
std::size_t bestSlack = 0;
924-
for (std::size_t column = 0; column < widths.size(); ++column)
925-
{
926-
if (!allowed[column] || widths[column] <= minimums[column])
927-
continue;
928-
929-
const std::size_t slack = widths[column] - minimums[column];
930-
if (best == static_cast<std::size_t>(-1) || widths[column] > bestWidth || (widths[column] == bestWidth && slack > bestSlack))
931-
{
932-
best = column;
933-
bestWidth = widths[column];
934-
bestSlack = slack;
935-
}
936-
}
937-
return best;
938-
}
939-
940-
void shrinkColumnsToBudget(std::vector<std::size_t> &widths, const std::vector<std::size_t> &minimums, const std::vector<bool> &allowed, std::size_t budget)
941-
{
942-
while (widthSum(widths) > budget)
943-
{
944-
const std::size_t column = largestShrinkableColumn(widths, minimums, allowed);
945-
if (column == static_cast<std::size_t>(-1))
946-
return;
947-
--widths[column];
948-
}
949-
}
950-
951-
std::vector<std::size_t> targetColumnWidthsForTableWidth(const Table &table, std::size_t maxTableWidth)
952-
{
953-
std::vector<std::size_t> widths = naturalColumnWidths(table);
954-
if (widths.empty())
955-
return widths;
956-
957-
const std::size_t overhead = formattedTableOverhead(table);
958-
if (maxTableWidth <= overhead + widths.size() * 3)
959-
maxTableWidth = overhead + widths.size() * 3;
960-
961-
const std::size_t budget = maxTableWidth - overhead;
962-
if (widthSum(widths) <= budget)
963-
return widths;
964-
965-
const std::vector<bool> textColumn = textColumns(table);
966-
std::vector<std::size_t> minimums(widths.size(), 3);
967-
std::vector<bool> allowed(widths.size(), false);
968-
for (std::size_t column = 0; column < widths.size(); ++column)
969-
{
970-
if (!textColumn[column])
971-
continue;
972-
minimums[column] = (std::min)(widths[column], preferredWrappedColumnWidth);
973-
allowed[column] = widths[column] > minimums[column];
974-
}
975-
shrinkColumnsToBudget(widths, minimums, allowed, budget);
976-
if (widthSum(widths) <= budget)
977-
return widths;
978-
979-
for (std::size_t column = 0; column < widths.size(); ++column)
980-
{
981-
if (!textColumn[column])
982-
continue;
983-
minimums[column] = (std::min)(widths[column], minimumWrappedColumnWidth);
984-
allowed[column] = widths[column] > minimums[column];
985-
}
986-
shrinkColumnsToBudget(widths, minimums, allowed, budget);
987-
if (widthSum(widths) <= budget)
988-
return widths;
989-
990-
for (std::size_t column = 0; column < widths.size(); ++column)
991-
{
992-
minimums[column] = (std::min)(widths[column], minimumWrappedColumnWidth);
993-
allowed[column] = widths[column] > minimums[column];
994-
}
995-
shrinkColumnsToBudget(widths, minimums, allowed, budget);
996-
if (widthSum(widths) <= budget)
997-
return widths;
998-
999-
for (std::size_t column = 0; column < widths.size(); ++column)
1000-
{
1001-
minimums[column] = 3;
1002-
allowed[column] = widths[column] > minimums[column];
1003-
}
1004-
shrinkColumnsToBudget(widths, minimums, allowed, budget);
1005-
return widths;
1006-
}
1007-
1008-
std::size_t wrapCellsToColumnWidths(Table &table, std::size_t originalTargetRow, const std::vector<std::size_t> &columnWidths)
1009-
{
1010-
if (table.separatorRow == static_cast<std::size_t>(-1) || columnWidths.size() < table.columns)
1011-
return originalTargetRow;
1012-
1013-
std::vector<Row> wrappedRows;
1014-
wrappedRows.reserve(table.rows.size());
1015-
std::size_t wrappedTargetRow = originalTargetRow;
1016-
std::size_t nextId = nextRowId(table);
1017-
1018-
for (std::size_t rowIndex = 0; rowIndex < table.rows.size(); ++rowIndex)
1019-
{
1020-
const Row &row = table.rows[rowIndex];
1021-
if (row.separator || rowIndex <= table.separatorRow)
1022-
{
1023-
if (rowIndex == originalTargetRow)
1024-
wrappedTargetRow = wrappedRows.size();
1025-
wrappedRows.push_back(row);
1026-
continue;
1027-
}
1028-
1029-
std::vector<std::vector<std::string>> cellSegments;
1030-
cellSegments.reserve(table.columns);
1031-
std::size_t segmentCount = 1;
1032-
for (std::size_t column = 0; column < table.columns; ++column)
1033-
{
1034-
cellSegments.push_back(wrapCellSegments(row.cells[column], columnWidths[column]));
1035-
segmentCount = (std::max)(segmentCount, cellSegments.back().size());
1036-
}
1037-
1038-
if (rowIndex == originalTargetRow)
1039-
wrappedTargetRow = wrappedRows.size();
1040-
1041-
for (std::size_t segmentIndex = 0; segmentIndex < segmentCount; ++segmentIndex)
1042-
{
1043-
Row wrapped;
1044-
wrapped.id = segmentIndex == 0 ? row.id : nextId++;
1045-
wrapped.cells.reserve(table.columns);
1046-
for (std::size_t column = 0; column < table.columns; ++column)
1047-
{
1048-
const std::vector<std::string> &segments = cellSegments[column];
1049-
wrapped.cells.push_back(segmentIndex < segments.size() ? segments[segmentIndex] : "");
1050-
}
1051-
wrappedRows.push_back(std::move(wrapped));
1052-
}
1053-
}
1054-
1055-
table.rows = std::move(wrappedRows);
1056-
return wrappedTargetRow;
1057-
}
1058-
1059851
void appendSeparatorCell(std::string &line, Align align, std::size_t width)
1060852
{
1061853
const std::size_t target = (std::max)(width, static_cast<std::size_t>(3));
@@ -2050,49 +1842,6 @@ EditResult apply(const std::vector<std::string> &lines, int row, int column, Act
20501842
return result;
20511843
}
20521844

2053-
EditResult applyWrappedToWidth(const std::vector<std::string> &lines, int row, int column, std::size_t maxTableWidth)
2054-
{
2055-
EditResult result;
2056-
if (lines.empty())
2057-
{
2058-
result.message = "No table found";
2059-
return result;
2060-
}
2061-
2062-
std::size_t sourceRow = row < 0 ? 0 : static_cast<std::size_t>(row);
2063-
if (sourceRow >= lines.size())
2064-
sourceRow = lines.size() - 1;
2065-
2066-
const TableRange tableRange = findTableRange(lines, static_cast<int>(sourceRow));
2067-
if (!tableRange.found)
2068-
{
2069-
result.message = "No Markdown table found";
2070-
return result;
2071-
}
2072-
2073-
std::size_t tableRow = sourceRow - tableRange.firstRow;
2074-
Table table = parseTable(lines, tableRange.firstRow, tableRange.lastRow);
2075-
if (!isMarkdownTable(table))
2076-
{
2077-
result.message = "No Markdown table found";
2078-
return result;
2079-
}
2080-
2081-
if (tableRow >= table.rows.size())
2082-
tableRow = table.rows.size() - 1;
2083-
std::size_t tableColumn = column < 0 ? 0 : static_cast<std::size_t>(column);
2084-
if (tableColumn >= table.columns)
2085-
tableColumn = table.columns - 1;
2086-
2087-
const std::vector<std::size_t> columnWidths = targetColumnWidthsForTableWidth(table, maxTableWidth);
2088-
const std::size_t targetRow = wrapCellsToColumnWidths(table, tableRow, columnWidths);
2089-
FormatResult formatted = formatTable(table, targetRow, tableColumn);
2090-
setResultFromFormat(result, formatted);
2091-
result.ok = true;
2092-
result.changed = true;
2093-
return result;
2094-
}
2095-
20961845
EditResult convertDelimitedToTable(const std::string &text)
20971846
{
20981847
EditResult result;

src/MarkdownTableCore.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ bool isPotentialTableLine(const std::string &line);
5050
std::size_t columnFromCursor(const std::string &line, std::size_t byteColumn);
5151
TableRange findTableRange(const std::vector<std::string> &lines, int row);
5252
EditResult apply(const std::vector<std::string> &lines, int row, int column, Action action);
53-
EditResult applyWrappedToWidth(const std::vector<std::string> &lines, int row, int column, std::size_t maxTableWidth);
5453
EditResult convertDelimitedToTable(const std::string &text);
5554
EditResult createTable(int columns, int dataRows);
5655
}

src/PluginDefinition.cpp

Lines changed: 3 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,55 +1156,6 @@ bool shouldApplyAutoWrapAfterAction(MarkdownTable::Action action)
11561156
return g_autoWrapLongCells && action == MarkdownTable::Action::Align;
11571157
}
11581158

1159-
int availableTextPixelWidth(HWND scintilla)
1160-
{
1161-
if (!scintilla)
1162-
return 0;
1163-
1164-
RECT client;
1165-
if (!::GetClientRect(scintilla, &client))
1166-
return 0;
1167-
1168-
const int safeMargin = 6;
1169-
const int availableWidth = (client.right - client.left) - safeMargin;
1170-
return availableWidth > 0 ? availableWidth : 0;
1171-
}
1172-
1173-
bool tableFitsAvailableWidth(HWND scintilla, const std::vector<std::string> &lines)
1174-
{
1175-
const int availableWidth = availableTextPixelWidth(scintilla);
1176-
if (availableWidth <= 0)
1177-
return false;
1178-
1179-
for (const auto &line : lines)
1180-
{
1181-
const LRESULT width = ::SendMessage(scintilla, SCI_TEXTWIDTH, 0, reinterpret_cast<LPARAM>(line.c_str()));
1182-
if (width > availableWidth)
1183-
return false;
1184-
}
1185-
return true;
1186-
}
1187-
1188-
std::size_t availableDisplayColumns(HWND scintilla)
1189-
{
1190-
const int availableWidth = availableTextPixelWidth(scintilla);
1191-
if (availableWidth <= 0)
1192-
return 80;
1193-
1194-
const std::string sample(80, '0');
1195-
const LRESULT sampleWidth = ::SendMessage(scintilla, SCI_TEXTWIDTH, 0, reinterpret_cast<LPARAM>(sample.c_str()));
1196-
if (sampleWidth <= 0)
1197-
return 80;
1198-
1199-
const std::size_t columns = static_cast<std::size_t>((static_cast<long long>(availableWidth) * static_cast<long long>(sample.size())) / sampleWidth);
1200-
return (std::max)(columns, static_cast<std::size_t>(20));
1201-
}
1202-
1203-
bool shouldApplyAutoWrapAfterAction(MarkdownTable::Action action, HWND scintilla, const std::vector<std::string> &previewLines)
1204-
{
1205-
return shouldApplyAutoWrapAfterAction(action) && !tableFitsAvailableWidth(scintilla, previewLines);
1206-
}
1207-
12081159
int coreIndex(std::size_t value)
12091160
{
12101161
const std::size_t maxInt = static_cast<std::size_t>((std::numeric_limits<int>::max)());
@@ -1649,13 +1600,13 @@ bool runTableAction(MarkdownTable::Action action, bool quiet)
16491600
showMessage(uiText().couldNotEditTable);
16501601
return false;
16511602
}
1652-
if (shouldApplyAutoWrapAfterAction(action, scintilla, edit.lines))
1603+
if (shouldApplyAutoWrapAfterAction(action))
16531604
{
1654-
MarkdownTable::EditResult wrapped = MarkdownTable::applyWrappedToWidth(
1605+
MarkdownTable::EditResult wrapped = MarkdownTable::apply(
16551606
edit.lines,
16561607
coreIndex(edit.targetRow),
16571608
coreIndex(edit.targetColumn),
1658-
availableDisplayColumns(scintilla));
1609+
MarkdownTable::Action::WrapLongCells);
16591610
if (wrapped.ok)
16601611
edit = wrapped;
16611612
}

tests/CoreSmoke.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -208,25 +208,6 @@ int main()
208208
"| | zeta eta theta |"
209209
});
210210

211-
const MarkdownTable::EditResult widthWrapped = MarkdownTable::applyWrappedToWidth(
212-
{
213-
"| Summary | Type | Priority | Reason | Id |",
214-
"| --- | --- | --- | --- | --- |",
215-
"| alpha beta gamma delta epsilon zeta eta theta | Task | High | one two three four five six seven | `abcdef0123456789` |"
216-
},
217-
2,
218-
0,
219-
80);
220-
expectTrue("wrap to table width ok", widthWrapped.ok);
221-
expectLines("wrap to table width keeps narrow columns", widthWrapped.lines,
222-
{
223-
"| Summary | Type | Priority | Reason | Id |",
224-
"| ---------------- | ---- | -------- | ------------- | ------------------ |",
225-
"| alpha beta gamma | Task | High | one two three | `abcdef0123456789` |",
226-
"| delta epsilon | | | four five six | |",
227-
"| zeta eta theta | | | seven | |"
228-
});
229-
230211
const MarkdownTable::EditResult wrappedProtectedTokens = MarkdownTable::apply(
231212
{
232213
"| Key | Value | Other |",

0 commit comments

Comments
 (0)