Skip to content

Commit 1e0c440

Browse files
committed
Even less unneeded isolates
1 parent aa0cff9 commit 1e0c440

File tree

4 files changed

+76
-47
lines changed

4 files changed

+76
-47
lines changed

core/katvan_highlighter.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void Highlighter::highlightBlock(const QString& text)
120120
parser.addListener(spanListener, false);
121121
parser.addListener(highlightingListener, true);
122122
parser.addListener(contentListenger, true);
123-
parser.addListener(isolatesListener, false);
123+
parser.addListener(isolatesListener, true);
124124

125125
parser.parse();
126126

core/katvan_parsing.cpp

+64-43
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,17 @@ static bool isCodeHolderState(const ParserState& state)
422422
|| state.kind == ParserState::Kind::CODE_ARGUMENTS;
423423
}
424424

425+
static bool isCodeState(const ParserState& state)
426+
{
427+
return isCodeHolderState(state)
428+
|| state.kind == ParserState::Kind::CODE_VARIABLE_NAME
429+
|| state.kind == ParserState::Kind::CODE_FUNCTION_NAME
430+
|| state.kind == ParserState::Kind::CODE_NUMERIC_LITERAL
431+
|| state.kind == ParserState::Kind::CODE_KEYWORD
432+
|| state.kind == ParserState::Kind::CODE_EXPRESSION_CHAIN
433+
|| state.kind == ParserState::Kind::CODE_STRING_EXPRESSION;
434+
}
435+
425436
void Parser::parse()
426437
{
427438
namespace m = matchers;
@@ -1125,8 +1136,6 @@ void IsolatesListener::initializeState(const ParserState& state, size_t endMarke
11251136

11261137
void IsolatesListener::finalizeState(const ParserState& state, size_t endMarker, bool implicit)
11271138
{
1128-
Q_UNUSED(implicit);
1129-
11301139
// What do we want to isolate the directionality of? Ideally short and
11311140
// _continuous_ bits of text associated with a state that typically involves
11321141
// characters with weak or no directionality. Math, inline code, content bits
@@ -1141,55 +1150,67 @@ void IsolatesListener::finalizeState(const ParserState& state, size_t endMarker,
11411150
d_codeSequenceRangesForLevel.takeLast();
11421151
}
11431152

1144-
if (state.kind == ParserState::Kind::CONTENT_REFERENCE) {
1145-
d_ranges.append(IsolateRange{ Qt::LayoutDirectionAuto, state.startPos, endMarker });
1146-
}
1147-
else if (state.kind == ParserState::Kind::CONTENT_BLOCK) {
1148-
// Don't include the square brackets in the isolate
1149-
d_ranges.append(IsolateRange{ Qt::LayoutDirectionAuto, state.startPos + 1, endMarker - 1 });
1150-
}
1151-
else if (state.kind == ParserState::Kind::MATH) {
1152-
d_ranges.append(IsolateRange{ Qt::LeftToRight, state.startPos, endMarker });
1153+
if (!implicit) {
1154+
if (state.kind == ParserState::Kind::CONTENT_REFERENCE) {
1155+
d_ranges.append(IsolateRange{ Qt::LayoutDirectionAuto, state.startPos, endMarker });
1156+
}
1157+
else if (state.kind == ParserState::Kind::CONTENT_BLOCK) {
1158+
// Don't include the square brackets in the isolate
1159+
d_ranges.append(IsolateRange{ Qt::LayoutDirectionAuto, state.startPos + 1, endMarker - 1 });
1160+
}
1161+
else if (state.kind == ParserState::Kind::MATH) {
1162+
d_ranges.append(IsolateRange{ Qt::LeftToRight, state.startPos, endMarker });
1163+
}
11531164
}
11541165

1155-
bool isIsolatableCode = state.kind == ParserState::Kind::CODE_VARIABLE_NAME
1156-
|| state.kind == ParserState::Kind::CODE_FUNCTION_NAME
1157-
|| state.kind == ParserState::Kind::CODE_ARGUMENTS
1158-
|| state.kind == ParserState::Kind::CODE_EXPRESSION_CHAIN
1159-
|| state.kind == ParserState::Kind::CODE_NUMERIC_LITERAL
1160-
|| state.kind == ParserState::Kind::CODE_STRING_EXPRESSION
1161-
|| state.kind == ParserState::Kind::CONTENT_BLOCK;
1166+
// Basically we want ANY code state to be considered so we have maximally
1167+
// long isolate ranges; but if any of it is something we don't want to
1168+
// isolate (code blocks, full lines, and parameter lists that spill to the
1169+
// next line), we can discard the whole thing.
1170+
if (isCodeState(state) || state.kind == ParserState::Kind::CONTENT_BLOCK) {
1171+
IsolateRange* codeRange = createOrUpdateCodeRange(state.kind, state.startPos, endMarker);
1172+
if (!codeRange) {
1173+
return;
1174+
}
11621175

1163-
if (isIsolatableCode) {
1164-
if (!d_codeSequenceRangesForLevel.last().isEmpty()) {
1165-
auto& existingRange = d_ranges[d_codeSequenceRangesForLevel.last().last()];
1176+
if (implicit || state.kind == ParserState::Kind::CODE_BLOCK || state.kind == ParserState::Kind::CODE_LINE) {
1177+
codeRange->discard = true;
1178+
}
1179+
}
1180+
}
11661181

1167-
if (state.startPos == existingRange.endPos + 1) {
1168-
// Extends existing isolated code range
1169-
existingRange.endPos = endMarker;
1170-
return;
1171-
}
1172-
else if (existingRange.startPos <= endMarker && existingRange.endPos >= state.startPos) {
1173-
// Intersects with existing isolated code range
1174-
size_t origStartPos = existingRange.startPos;
1175-
existingRange.startPos = qMin(existingRange.startPos, state.startPos);
1176-
existingRange.endPos = qMax(existingRange.endPos, endMarker);
1177-
1178-
if (existingRange.startPos < origStartPos) {
1179-
discardRedundantCodeRanges();
1180-
}
1181-
return;
1182+
IsolateRange* IsolatesListener::createOrUpdateCodeRange(ParserState::Kind state, size_t startPos, size_t endPos)
1183+
{
1184+
if (!d_codeSequenceRangesForLevel.last().isEmpty()) {
1185+
auto& existingRange = d_ranges[d_codeSequenceRangesForLevel.last().last()];
1186+
1187+
if (startPos == existingRange.endPos + 1) {
1188+
// Extends existing isolated code range
1189+
existingRange.endPos = endPos;
1190+
return &existingRange;
1191+
}
1192+
else if (existingRange.startPos <= endPos && existingRange.endPos >= startPos) {
1193+
// Intersects with existing isolated code range
1194+
size_t origStartPos = existingRange.startPos;
1195+
existingRange.startPos = qMin(existingRange.startPos, startPos);
1196+
existingRange.endPos = qMax(existingRange.endPos, endPos);
1197+
1198+
if (existingRange.startPos < origStartPos) {
1199+
discardRedundantCodeRanges();
11821200
}
1201+
return &existingRange;
11831202
}
1203+
}
11841204

1185-
// No existing isolated code range in this nesting level, or does not
1186-
// intersect. Start a new one, but not for content blocks as they have
1187-
// special handling above.
1188-
if (state.kind != ParserState::Kind::CONTENT_BLOCK) {
1189-
d_codeSequenceRangesForLevel.last().append(d_ranges.size());
1190-
d_ranges.append(IsolateRange{ Qt::LeftToRight, state.startPos, endMarker });
1191-
}
1205+
// No existing isolated code range in this nesting level, or does not
1206+
// intersect. Start a new one, but not for content blocks as they have
1207+
// special handling in finalizeState.
1208+
if (state != ParserState::Kind::CONTENT_BLOCK) {
1209+
d_codeSequenceRangesForLevel.last().append(d_ranges.size());
1210+
d_ranges.append(IsolateRange{ Qt::LeftToRight, startPos, endPos });
1211+
return &d_ranges.last();
11921212
}
1213+
return nullptr;
11931214
}
11941215

11951216
void IsolatesListener::discardRedundantCodeRanges()

core/katvan_parsing.h

+1
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ class IsolatesListener : public ParsingListener
313313
void finalizeState(const ParserState& state, size_t endMarker, bool implicit) override;
314314

315315
private:
316+
IsolateRange* createOrUpdateCodeRange(ParserState::Kind state, size_t startPos, size_t endPos);
316317
void discardRedundantCodeRanges();
317318

318319
IsolateRangeList d_ranges;

tests/katvan_parsing.t.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ static IsolateRangeList extractIsolates(QStringView text)
790790
{
791791
IsolatesListener listener;
792792
Parser parser(text);
793-
parser.addListener(listener, false);
793+
parser.addListener(listener, true);
794794
parser.parse();
795795
return listener.isolateRanges();
796796
}
@@ -819,13 +819,20 @@ TEST(IsolatesListenerTests, Math)
819819

820820
TEST(IsolatesListenerTests, CodeNumbers)
821821
{
822-
auto isolates = extractIsolates(QStringLiteral("#par(leading: 1em, spacing: 2px)"));
822+
auto isolates = extractIsolates(QStringLiteral("#par(leading: 1em, spacing: 2px, text: `foo`)"));
823823

824824
EXPECT_THAT(isolates, ::testing::ElementsAre(
825-
IsolateRange { Qt::LeftToRight, 0, 31 } // The whole thing
825+
IsolateRange { Qt::LeftToRight, 0, 44 } // The whole thing
826826
));
827827
}
828828

829+
TEST(IsolatesListenerTests, CodeLine)
830+
{
831+
auto isolates = extractIsolates(QStringLiteral("#set text(lang: \"he\")"));
832+
833+
EXPECT_THAT(isolates, ::testing::IsEmpty());
834+
}
835+
829836
TEST(IsolatesListenerTests, Nesting)
830837
{
831838
auto isolates = extractIsolates(QStringLiteral(

0 commit comments

Comments
 (0)