Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Notepad3 is a free, open-source text editor with syntax highlighting for Windows
- **Mark all occurrences** of a selected word with occurrence count display
- **Find and Replace** with [PCRE2](https://github.com/PCRE2Project/pcre2) regular expression engine
- **[Focused View](readme/focusedview/FocusedView.md)** — filter display to show only lines matching the current word/selection (Ctrl+Alt+V), with fold, bookmark, and highlight modes
- **[TinyExpr++](https://blake-madden.github.io/tinyexpr-plusplus/)** — inline math expression evaluation with 80+ functions (type `expression=?` to evaluate in-place, use `${expr}` in line numbering). See the [Expression Engine Guide](readme/tinyexprcpp/TinyExprPP.md) for details.
- **[TinyExpr++](readme/tinyexprcpp/TinyExprPP.md)** — inline math expression evaluation with 80+ functions (type `expression=?` to evaluate in-place, use `${expr}` in line numbering).
- **Undo/Redo** that preserves selection state
- **Visual Studio–style** copy/paste of the current line (when nothing is selected)
- **Virtual space** rectangular selection (Alt+Drag)
Expand Down
1 change: 1 addition & 0 deletions language/common_res.h
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@
#define IDM_VIEW_CHGHIST_ALL 41062 // SC_CHANGE_HISTORY_ENABLED | SC_CHANGE_HISTORY_MARKERS | SC_CHANGE_HISTORY_INDICATORS
#define IDM_VIEW_CHGHIST_TOGGLE_MARGIN 41063
#define IDM_VIEW_CHGHIST_CLEAR_UNDOREDO 41064
#define IDM_VIEW_NONPRINTINGCHARS 41065

// keep Scintilla(SC) order
#define IDM_SET_RENDER_TECH_GDI 42000 // SC_TECHNOLOGY_DEFAULT(0)
Expand Down
1 change: 1 addition & 0 deletions language/np3_af_za/menu_af_za.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Wys &Oorvloei Simbole\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "W&ys Oop Spasies\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Wys Lyn &Einde\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Verander Geskiedenismerker"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_be_by/menu_be_by.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Паказваць &сімвалы пераносаў\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Паказваць прабельныя сімва&лы\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Паказваць &канчаткі радкоў\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Маркер гісторыі змяненняў"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_de_de/menu_de_de.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Zeige Umbruchsymbole\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Zeige Leerzeichen\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Zeige Zeilenumbrüche\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Zeige nicht-druckbare &Zeichen", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Änderungshistorie Markierung"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_el_gr/menu_el_gr.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Εμφάνιση &συμβόλων αναδίπλωσης\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Εμφάνιση &κενών διαστημάτων\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Εμφάνιση καταλή&ξεων γραμμών\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Ενδείξεις αλλαγών"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_en_gb/menu_en_gb.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Show W&rap Symbols\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Show &Blanks\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Show Line &Endings\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Change History Marker"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_en_us/menu_en_us.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Show W&rap Symbols\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Show &Blanks\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Show Line &Endings\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Change History Marker"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_es_es/menu_es_es.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Mostrar &símbolos de ajuste\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Mostrar los &Blancos\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Mostrar &fin de línea\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Marcadores historial de cambios"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_fi_fi/menu_fi_fi.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Näytä &rivityssymbolit\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Näytä &tyhjät tilat\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Näytä rivin lop&etukset\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Vaihda historiamerkintä"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_fr_fr/menu_fr_fr.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Afficher les symbôles de sauts de ligne\tCtrl+Maj+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Afficher les &blancs\tCtrl+Maj+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Afficher les fins de lign&e\tCtrl+Maj+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Marqueurs d'historique des modifications"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_hi_in/menu_hi_in.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "लपेटे हुए चिन्ह दिखाएं (&P)\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "खाली स्थान दिखाएं (&B)\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "वाक्य अंत दिखाएं (&E)\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "परिवर्तन इतिहास मार्कर"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_hu_hu/menu_hu_hu.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Sortö&rés jelzése\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Sz&óközök megjelenítése\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Sorvégek &megjelenítése\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Előzményjelölők megváltoztatása"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_id_id/menu_id_id.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Tampilkan Simbol Bungkus Kata\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Tampilkan Spasi\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Tampilkan Akhir Baris\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Penanda Riwayat"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_it_it/menu_it_it.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Visualizza simboli di a capo\tCtrl+Maiusc+0", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Visualizza spazi\tCtrl+Maiusc+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Visualizza terminazioni di linea\tCtrl+Maiusc+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Marcatore cronologia modifiche"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_ja_jp/menu_ja_jp.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "折り返し記号(&P)\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "空白(&W)\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "改行コード(&E)\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "変更履歴の目印"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_ko_kr/menu_ko_kr.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "줄 바꿈 기호 표시(&P)\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "공백 표시(&B)\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "줄 끝 표시(&E)\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "사용 내역 마커 변경"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_nl_nl/menu_nl_nl.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Terugloo&pmarkeringen weergeven\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "&Blanco's weergeven\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Regel&einden weergeven\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Markering van wijzigingen"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_pl_pl/menu_pl_pl.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Pokaż symbole zawijania wiersza\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Pokaż niewidoczne znaki \tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Pokaż znaki końca wiersza\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Zmień marker historii"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_pt_br/menu_pt_br.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Mostrar Símbolos de Q&uebra\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Mostrar &Espaços\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Mostrar &Finais de Linha\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Alterar Marcador de Histórico"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_pt_pt/menu_pt_pt.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Mostrar símbolos de mudança de linha\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Mostrar espaços\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Mostrar fins d&e linha\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Marcador do histórico de alterações"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_ru_ru/menu_ru_ru.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Отображать &символы переноса\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Отображать про&бельные символы\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Отображать &окончания строк\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Маркер истории изменений"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_sk_sk/menu_sk_sk.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Zobraziť &symboly zalomenia\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Zobraziť &prázdne miesta\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Zobraziť &konce riadkov\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Značka histórie zmien"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_sv_se/menu_sv_se.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Visa radbrytningssymboler\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Visa blanksteg\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Visa radslut\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Markör för ändringshistorik"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_tr_tr/menu_tr_tr.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Satır kaydırmaları görüntülensin\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Boşluklar görüntülensin\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Satır sonları görüntülensin\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Değişiklik geçmişi işareti"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_vi_vn/menu_vi_vn.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "Hiển thị ký hiệu ngắt dòng(&P)\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "Hiển thị khoảng trắng(&B)\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "Hiển thị ký hiệu kết thúc dòng(&E)\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "Thay đổi dấu hiệu thay đổi"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_zh_cn/menu_zh_cn.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "显示软换行(&P)\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "显示空格(&W)\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "显示换行符号(&E)\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "变更记录标记"
BEGIN
Expand Down
1 change: 1 addition & 0 deletions language/np3_zh_tw/menu_zh_tw.rc
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ BEGIN
MENUITEM "顯示軟換行(&P)\tCtrl+Shift+7", IDM_VIEW_WORDWRAPSYMBOLS
MENUITEM "顯示空格(&W)\tCtrl+Shift+8", IDM_VIEW_SHOWBLANKS
MENUITEM "顯示換行符號(&E)\tCtrl+Shift+9", IDM_VIEW_SHOWEOLS
MENUITEM "Show &Non-Printable Characters", IDM_VIEW_NONPRINTINGCHARS
MENUITEM SEPARATOR
POPUP "變更記錄標記"
BEGIN
Expand Down
62 changes: 38 additions & 24 deletions scintilla/pcre2/scintilla/PCRE2RegExEngine.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class PCRE2RegExEngine : public RegexSearchBase
public:

explicit PCRE2RegExEngine(CharClassify* /*charClassTable*/)
: m_CompileOptions(PCRE2_UTF | PCRE2_UCP | PCRE2_MULTILINE)
: m_CompileOptions(PCRE2_UTF | PCRE2_UCP | PCRE2_MULTILINE | PCRE2_USE_OFFSET_LIMIT)
, m_CompiledPattern(nullptr)
, m_MatchData(nullptr)
, m_CompileContext(nullptr)
Expand Down Expand Up @@ -261,8 +261,11 @@ Sci::Position PCRE2RegExEngine::FindText(Document* doc, Sci::Position minPos, Sc

// --- Build compile options ---
// PCRE2_MULTILINE: ^/$ match at line boundaries
// PCRE2_USE_OFFSET_LIMIT: enables pcre2_set_offset_limit() on the match context;
// set unconditionally so the bit is part of the recompile cache key and
// forward/backward share one compiled pattern.
// Newline convention (ANYCRLF) is set on m_CompileContext, not here
uint32_t compileOptions = PCRE2_UTF | PCRE2_UCP | PCRE2_MULTILINE;
uint32_t compileOptions = PCRE2_UTF | PCRE2_UCP | PCRE2_MULTILINE | PCRE2_USE_OFFSET_LIMIT;

if (!caseSensitive) {
compileOptions |= PCRE2_CASELESS;
Expand Down Expand Up @@ -346,6 +349,9 @@ Sci::Position PCRE2RegExEngine::FindText(Document* doc, Sci::Position minPos, Sc

if (findForward) {
// --- Forward search ---
// Clear any offset_limit a prior backward call left on the shared match context.
pcre2_set_offset_limit(m_MatchContext, PCRE2_UNSET);

int rc = pcre2_match(
m_CompiledPattern,
docBegPtr,
Expand Down Expand Up @@ -378,11 +384,21 @@ Sci::Position PCRE2RegExEngine::FindText(Document* doc, Sci::Position minPos, Sc
// range forward (O(n)), we search in reverse chunks starting near rangeEnd.
// Each chunk searches forward within a window and keeps the last match.
// Average case is O(chunk_size) instead of O(range_size).
//
// PCRE2_USE_OFFSET_LIMIT (compile flag) + pcre2_set_offset_limit() let the
// engine itself prune match attempts whose start position would exceed
// rangeEnd, so the inner loop needs no post-match bounds check.
pcre2_set_offset_limit(m_MatchContext, static_cast<PCRE2_SIZE>(rangeEnd));

Sci::Position lastMatchPos = SciPos(-1);
Sci::Position lastMatchLen = SciPos(0);

pcre2_match_data* iterMatchData = pcre2_match_data_create_from_pattern(m_CompiledPattern, nullptr);
// Snapshot the ovector of the rightmost successful match so the loop can
// keep advancing without losing it. Sized for the same cap that
// SubstituteByPosition supports ($0..$99 → 100 pairs).
constexpr size_t kMaxOvecPairs = 100;
PCRE2_SIZE savedOvec[kMaxOvecPairs * 2];
uint32_t savedOvecCount = 0;

Sci::Position const chunkSize = 4096; // search window size
Sci::Position chunkStart = (rangeEnd > chunkSize) ? (rangeEnd - chunkSize) : rangeBeg;
Expand All @@ -403,25 +419,28 @@ Sci::Position PCRE2RegExEngine::FindText(Document* doc, Sci::Position minPos, Sc
docLen,
searchStart,
matchOptions,
iterMatchData,
m_MatchData,
m_MatchContext
);

if (rc <= 0) break; // no more matches
if (rc <= 0) break; // no more matches (offset_limit enforces upper bound)

PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(iterMatchData);
Sci::Position pos = SciPos(ovector[0]);
Sci::Position len = SciPos(ovector[1]) - pos;
PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(m_MatchData);
uint32_t ovecCount = pcre2_get_ovector_count(m_MatchData);
if (ovecCount > kMaxOvecPairs) ovecCount = kMaxOvecPairs;
memcpy(savedOvec, ovector, ovecCount * 2 * sizeof(PCRE2_SIZE));
savedOvecCount = ovecCount;

if (pos > rangeEnd) break; // past search range
Sci::Position pos = SciPos(savedOvec[0]);
Sci::Position len = SciPos(savedOvec[1]) - pos;

lastMatchPos = pos;
lastMatchLen = len;
found = true;

// Advance past this match (at least 1 byte, handle UTF-8)
if (ovector[1] > ovector[0]) {
searchStart = ovector[1];
if (savedOvec[1] > savedOvec[0]) {
searchStart = savedOvec[1];
} else {
searchStart = static_cast<PCRE2_SIZE>(
doc->MovePositionOutsideChar(SciPos(searchStart + 1), 1, true)
Expand All @@ -442,21 +461,16 @@ Sci::Position PCRE2RegExEngine::FindText(Document* doc, Sci::Position minPos, Sc
}
}

// Re-run the match at the final position to populate m_MatchData for SubstituteByPosition
if (lastMatchPos >= 0) {
pcre2_match(
m_CompiledPattern,
docBegPtr,
docLen,
static_cast<PCRE2_SIZE>(lastMatchPos),
matchOptions | PCRE2_ANCHORED,
m_MatchData,
m_MatchContext
);
// Restore the rightmost-match ovector into m_MatchData so SubstituteByPosition
// sees the correct groups. The loop's final pcre2_match call returned
// PCRE2_ERROR_NOMATCH and left m_MatchData's ovector in an undefined state;
// memcpy'ing the snapshot back is cheaper than a re-anchored pcre2_match call.
if (lastMatchPos >= 0 && savedOvecCount > 0) {
memcpy(pcre2_get_ovector_pointer(m_MatchData),
savedOvec,
savedOvecCount * 2 * sizeof(PCRE2_SIZE));
}

pcre2_match_data_free(iterMatchData);

m_MatchPos = lastMatchPos;
m_MatchLen = lastMatchLen;
}
Expand Down
Loading
Loading