2009-04-24 23:35:41 +00:00
|
|
|
// Scintilla source code edit control
|
|
|
|
/** @file Document.cxx
|
|
|
|
** Text document that handles notifications, DBCS, styling, words and end of line.
|
|
|
|
**/
|
2011-07-17 22:30:49 +00:00
|
|
|
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
|
2009-04-24 23:35:41 +00:00
|
|
|
// The License.txt file describes the conditions under which this software may be distributed.
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstring>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cmath>
|
2009-04-24 23:35:41 +00:00
|
|
|
|
2015-06-07 21:19:26 +00:00
|
|
|
#include <stdexcept>
|
2010-07-12 22:19:51 +00:00
|
|
|
#include <string>
|
2019-05-04 18:14:48 +00:00
|
|
|
#include <string_view>
|
2010-07-12 22:19:51 +00:00
|
|
|
#include <vector>
|
2023-11-05 17:24:41 +00:00
|
|
|
#include <array>
|
2019-05-04 18:14:48 +00:00
|
|
|
#include <forward_list>
|
2022-01-04 23:07:50 +00:00
|
|
|
#include <optional>
|
2013-08-28 00:44:27 +00:00
|
|
|
#include <algorithm>
|
2019-05-04 18:14:48 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <chrono>
|
2010-07-12 22:19:51 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
#ifndef NO_CXX11_REGEX
|
2015-06-07 21:19:26 +00:00
|
|
|
#include <regex>
|
|
|
|
#endif
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
#include "ScintillaTypes.h"
|
2019-05-04 18:14:48 +00:00
|
|
|
#include "ILoader.h"
|
2010-08-21 23:59:56 +00:00
|
|
|
#include "ILexer.h"
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
#include "Debugging.h"
|
|
|
|
|
|
|
|
#include "CharacterType.h"
|
|
|
|
#include "CharacterCategoryMap.h"
|
2019-05-04 18:14:48 +00:00
|
|
|
#include "Position.h"
|
2009-04-24 23:35:41 +00:00
|
|
|
#include "SplitVector.h"
|
|
|
|
#include "Partitioning.h"
|
|
|
|
#include "RunStyles.h"
|
|
|
|
#include "CellBuffer.h"
|
2009-06-24 19:09:31 +00:00
|
|
|
#include "PerLine.h"
|
2009-04-24 23:35:41 +00:00
|
|
|
#include "CharClassify.h"
|
|
|
|
#include "Decoration.h"
|
2013-08-28 00:44:27 +00:00
|
|
|
#include "CaseFolder.h"
|
2009-04-24 23:35:41 +00:00
|
|
|
#include "Document.h"
|
|
|
|
#include "RESearch.h"
|
2010-07-12 22:19:51 +00:00
|
|
|
#include "UniConversion.h"
|
2019-05-04 18:14:48 +00:00
|
|
|
#include "ElapsedPeriod.h"
|
2009-04-24 23:35:41 +00:00
|
|
|
|
|
|
|
using namespace Scintilla;
|
2022-01-04 23:07:50 +00:00
|
|
|
using namespace Scintilla::Internal;
|
|
|
|
|
|
|
|
LexInterface::LexInterface(Document *pdoc_) noexcept : pdoc(pdoc_), performingStyle(false) {
|
|
|
|
}
|
|
|
|
|
|
|
|
LexInterface::~LexInterface() noexcept = default;
|
|
|
|
|
2022-12-10 12:35:16 +00:00
|
|
|
void LexInterface::SetInstance(ILexer5 *instance_) noexcept {
|
2022-01-04 23:07:50 +00:00
|
|
|
instance.reset(instance_);
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void LexInterface::Colourise(Sci::Position start, Sci::Position end) {
|
2010-08-21 23:59:56 +00:00
|
|
|
if (pdoc && instance && !performingStyle) {
|
|
|
|
// Protect against reentrance, which may occur, for example, when
|
|
|
|
// fold points are discovered while performing styling and the folding
|
|
|
|
// code looks for child lines which may trigger styling.
|
|
|
|
performingStyle = true;
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position lengthDoc = pdoc->Length();
|
2010-08-21 23:59:56 +00:00
|
|
|
if (end == -1)
|
|
|
|
end = lengthDoc;
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position len = end - start;
|
2010-08-21 23:59:56 +00:00
|
|
|
|
|
|
|
PLATFORM_ASSERT(len >= 0);
|
|
|
|
PLATFORM_ASSERT(start + len <= lengthDoc);
|
|
|
|
|
|
|
|
int styleStart = 0;
|
|
|
|
if (start > 0)
|
2015-06-07 21:19:26 +00:00
|
|
|
styleStart = pdoc->StyleAt(start - 1);
|
2010-08-21 23:59:56 +00:00
|
|
|
|
|
|
|
if (len > 0) {
|
|
|
|
instance->Lex(start, len, styleStart, pdoc);
|
|
|
|
instance->Fold(start, len, styleStart, pdoc);
|
|
|
|
}
|
|
|
|
|
|
|
|
performingStyle = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
LineEndType LexInterface::LineEndTypesSupported() {
|
2013-08-28 00:44:27 +00:00
|
|
|
if (instance) {
|
2022-01-04 23:07:50 +00:00
|
|
|
return static_cast<LineEndType>(instance->LineEndTypesSupported());
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
return LineEndType::Default;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LexInterface::UseContainerLexing() const noexcept {
|
|
|
|
return !instance;
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
ActionDuration::ActionDuration(double duration_, double minDuration_, double maxDuration_) noexcept :
|
|
|
|
duration(duration_), minDuration(minDuration_), maxDuration(maxDuration_) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionDuration::AddSample(size_t numberActions, double durationOfActions) noexcept {
|
|
|
|
// Only adjust for multiple actions to avoid instability
|
|
|
|
if (numberActions < 8)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Alpha value for exponential smoothing.
|
|
|
|
// Most recent value contributes 25% to smoothed value.
|
2021-02-21 04:53:09 +00:00
|
|
|
constexpr double alpha = 0.25;
|
2019-05-04 18:14:48 +00:00
|
|
|
|
|
|
|
const double durationOne = durationOfActions / numberActions;
|
|
|
|
duration = std::clamp(alpha * durationOne + (1.0 - alpha) * duration,
|
|
|
|
minDuration, maxDuration);
|
|
|
|
}
|
|
|
|
|
|
|
|
double ActionDuration::Duration() const noexcept {
|
|
|
|
return duration;
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
size_t ActionDuration::ActionsInAllowedTime(double secondsAllowed) const noexcept {
|
|
|
|
return std::lround(secondsAllowed / Duration());
|
|
|
|
}
|
|
|
|
|
2022-12-10 12:35:16 +00:00
|
|
|
CharacterExtracted::CharacterExtracted(const unsigned char *charBytes, size_t widthCharBytes) noexcept {
|
|
|
|
const int utf8status = UTF8Classify(charBytes, widthCharBytes);
|
|
|
|
if (utf8status & UTF8MaskInvalid) {
|
|
|
|
// Treat as invalid and use up just one byte
|
|
|
|
character = unicodeReplacementChar;
|
|
|
|
widthBytes = 1;
|
|
|
|
} else {
|
|
|
|
character = UnicodeFromUTF8(charBytes);
|
|
|
|
widthBytes = utf8status & UTF8MaskWidth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
Document::Document(DocumentOption options) :
|
|
|
|
cb(!FlagSet(options, DocumentOption::StylesNone), FlagSet(options, DocumentOption::TextLarge)),
|
|
|
|
durationStyleOneByte(0.000001, 0.0000001, 0.00001) {
|
2009-04-24 23:35:41 +00:00
|
|
|
refCount = 0;
|
2013-08-28 00:44:27 +00:00
|
|
|
#ifdef _WIN32
|
2022-01-04 23:07:50 +00:00
|
|
|
eolMode = EndOfLine::CrLf;
|
2013-08-28 00:44:27 +00:00
|
|
|
#else
|
2022-01-04 23:07:50 +00:00
|
|
|
eolMode = EndOfLine::Lf;
|
2009-04-24 23:35:41 +00:00
|
|
|
#endif
|
2022-01-04 23:07:50 +00:00
|
|
|
dbcsCodePage = CpUtf8;
|
|
|
|
lineEndBitSet = LineEndType::Default;
|
2009-04-24 23:35:41 +00:00
|
|
|
endStyled = 0;
|
|
|
|
styleClock = 0;
|
|
|
|
enteredModification = 0;
|
|
|
|
enteredStyling = 0;
|
|
|
|
enteredReadOnlyCount = 0;
|
2015-06-07 21:19:26 +00:00
|
|
|
insertionSet = false;
|
2009-04-24 23:35:41 +00:00
|
|
|
tabInChars = 8;
|
|
|
|
indentInChars = 0;
|
|
|
|
actualIndentInChars = 8;
|
|
|
|
useTabs = true;
|
|
|
|
tabIndents = true;
|
|
|
|
backspaceUnindents = false;
|
|
|
|
|
|
|
|
matchesValid = false;
|
2009-06-24 19:09:31 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
perLineData[ldMarkers] = std::make_unique<LineMarkers>();
|
|
|
|
perLineData[ldLevels] = std::make_unique<LineLevels>();
|
|
|
|
perLineData[ldState] = std::make_unique<LineState>();
|
|
|
|
perLineData[ldMargin] = std::make_unique<LineAnnotation>();
|
|
|
|
perLineData[ldAnnotation] = std::make_unique<LineAnnotation>();
|
2021-02-21 04:53:09 +00:00
|
|
|
perLineData[ldEOLAnnotation] = std::make_unique<LineAnnotation>();
|
2013-08-28 00:44:27 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
decorations = DecorationListCreate(IsLarge());
|
2009-06-24 19:09:31 +00:00
|
|
|
|
|
|
|
cb.SetPerLine(this);
|
2022-01-04 23:07:50 +00:00
|
|
|
cb.SetUTF8Substance(CpUtf8 == dbcsCodePage);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Document::~Document() {
|
2019-05-04 18:14:48 +00:00
|
|
|
for (const WatcherWithUserData &watcher : watchers) {
|
|
|
|
watcher.watcher->NotifyDeleted(this, watcher.userData);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Increase reference count and return its previous value.
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
int SCI_METHOD Document::AddRef() noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
return refCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Decrease reference count and return its previous value.
|
|
|
|
// Delete the document if reference count reaches zero.
|
|
|
|
int SCI_METHOD Document::Release() {
|
|
|
|
const int curRefCount = --refCount;
|
|
|
|
if (curRefCount == 0)
|
|
|
|
delete this;
|
|
|
|
return curRefCount;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2009-08-23 02:24:48 +00:00
|
|
|
void Document::Init() {
|
2019-05-04 18:14:48 +00:00
|
|
|
for (const std::unique_ptr<PerLine> &pl : perLineData) {
|
|
|
|
if (pl)
|
|
|
|
pl->Init();
|
2009-08-23 02:24:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::InsertLine(Sci::Line line) {
|
|
|
|
for (const std::unique_ptr<PerLine> &pl : perLineData) {
|
|
|
|
if (pl)
|
|
|
|
pl->InsertLine(line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
void Document::InsertLines(Sci::Line line, Sci::Line lines) {
|
|
|
|
for (const auto &pl : perLineData) {
|
|
|
|
if (pl)
|
|
|
|
pl->InsertLines(line, lines);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::RemoveLine(Sci::Line line) {
|
|
|
|
for (const std::unique_ptr<PerLine> &pl : perLineData) {
|
|
|
|
if (pl)
|
|
|
|
pl->RemoveLine(line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
LineMarkers *Document::Markers() const noexcept {
|
2023-02-09 16:57:24 +00:00
|
|
|
return static_cast<LineMarkers *>(perLineData[ldMarkers].get());
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
LineLevels *Document::Levels() const noexcept {
|
2023-02-09 16:57:24 +00:00
|
|
|
return static_cast<LineLevels *>(perLineData[ldLevels].get());
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
LineState *Document::States() const noexcept {
|
2023-02-09 16:57:24 +00:00
|
|
|
return static_cast<LineState *>(perLineData[ldState].get());
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
LineAnnotation *Document::Margins() const noexcept {
|
2023-02-09 16:57:24 +00:00
|
|
|
return static_cast<LineAnnotation *>(perLineData[ldMargin].get());
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
LineAnnotation *Document::Annotations() const noexcept {
|
2023-02-09 16:57:24 +00:00
|
|
|
return static_cast<LineAnnotation *>(perLineData[ldAnnotation].get());
|
2021-02-21 04:53:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LineAnnotation *Document::EOLAnnotations() const noexcept {
|
2023-02-09 16:57:24 +00:00
|
|
|
return static_cast<LineAnnotation *>(perLineData[ldEOLAnnotation].get());
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
LineEndType Document::LineEndTypesSupported() const {
|
|
|
|
if ((CpUtf8 == dbcsCodePage) && pli)
|
2013-08-28 00:44:27 +00:00
|
|
|
return pli->LineEndTypesSupported();
|
|
|
|
else
|
2022-01-04 23:07:50 +00:00
|
|
|
return LineEndType::Default;
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Document::SetDBCSCodePage(int dbcsCodePage_) {
|
|
|
|
if (dbcsCodePage != dbcsCodePage_) {
|
|
|
|
dbcsCodePage = dbcsCodePage_;
|
2019-05-04 18:14:48 +00:00
|
|
|
SetCaseFolder(nullptr);
|
2013-08-28 00:44:27 +00:00
|
|
|
cb.SetLineEndTypes(lineEndBitSet & LineEndTypesSupported());
|
2022-01-04 23:07:50 +00:00
|
|
|
cb.SetUTF8Substance(CpUtf8 == dbcsCodePage);
|
2019-05-04 18:14:48 +00:00
|
|
|
ModifiedAt(0); // Need to restyle whole document
|
2013-08-28 00:44:27 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
bool Document::SetLineEndTypesAllowed(LineEndType lineEndBitSet_) {
|
2013-08-28 00:44:27 +00:00
|
|
|
if (lineEndBitSet != lineEndBitSet_) {
|
|
|
|
lineEndBitSet = lineEndBitSet_;
|
2022-01-04 23:07:50 +00:00
|
|
|
const LineEndType lineEndBitSetActive = lineEndBitSet & LineEndTypesSupported();
|
2013-08-28 00:44:27 +00:00
|
|
|
if (lineEndBitSetActive != cb.GetLineEndTypes()) {
|
|
|
|
ModifiedAt(0);
|
|
|
|
cb.SetLineEndTypes(lineEndBitSetActive);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-24 23:35:41 +00:00
|
|
|
void Document::SetSavePoint() {
|
|
|
|
cb.SetSavePoint();
|
|
|
|
NotifySavePoint(true);
|
|
|
|
}
|
|
|
|
|
2015-06-07 21:19:26 +00:00
|
|
|
void Document::TentativeUndo() {
|
|
|
|
if (!TentativeActive())
|
|
|
|
return;
|
|
|
|
CheckReadOnly();
|
|
|
|
if (enteredModification == 0) {
|
|
|
|
enteredModification++;
|
|
|
|
if (!cb.IsReadOnly()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const bool startSavePoint = cb.IsSavePoint();
|
2015-06-07 21:19:26 +00:00
|
|
|
bool multiLine = false;
|
2019-05-04 18:14:48 +00:00
|
|
|
const int steps = cb.TentativeSteps();
|
2015-06-07 21:19:26 +00:00
|
|
|
//Platform::DebugPrintf("Steps=%d\n", steps);
|
|
|
|
for (int step = 0; step < steps; step++) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line prevLinesTotal = LinesTotal();
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
const Action action = cb.GetUndoStep();
|
2022-01-04 23:07:50 +00:00
|
|
|
if (action.at == ActionType::remove) {
|
2015-06-07 21:19:26 +00:00
|
|
|
NotifyModified(DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::BeforeInsert | ModificationFlags::Undo, action));
|
|
|
|
} else if (action.at == ActionType::container) {
|
|
|
|
DocModification dm(ModificationFlags::Container | ModificationFlags::Undo);
|
2015-06-07 21:19:26 +00:00
|
|
|
dm.token = action.position;
|
|
|
|
NotifyModified(dm);
|
|
|
|
} else {
|
|
|
|
NotifyModified(DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::BeforeDelete | ModificationFlags::Undo, action));
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
|
|
|
cb.PerformUndoStep();
|
2022-01-04 23:07:50 +00:00
|
|
|
if (action.at != ActionType::container) {
|
2015-06-07 21:19:26 +00:00
|
|
|
ModifiedAt(action.position);
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags modFlags = ModificationFlags::Undo;
|
2015-06-07 21:19:26 +00:00
|
|
|
// With undo, an insertion action becomes a deletion notification
|
2022-01-04 23:07:50 +00:00
|
|
|
if (action.at == ActionType::remove) {
|
|
|
|
modFlags |= ModificationFlags::InsertText;
|
|
|
|
} else if (action.at == ActionType::insert) {
|
|
|
|
modFlags |= ModificationFlags::DeleteText;
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
|
|
|
if (steps > 1)
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::MultiStepUndoRedo;
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line linesAdded = LinesTotal() - prevLinesTotal;
|
2015-06-07 21:19:26 +00:00
|
|
|
if (linesAdded != 0)
|
|
|
|
multiLine = true;
|
|
|
|
if (step == steps - 1) {
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::LastStepInUndoRedo;
|
2015-06-07 21:19:26 +00:00
|
|
|
if (multiLine)
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::MultilineUndoRedo;
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
|
|
|
NotifyModified(DocModification(modFlags, action.position, action.lenData,
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
linesAdded, action.data));
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
const bool endSavePoint = cb.IsSavePoint();
|
2015-06-07 21:19:26 +00:00
|
|
|
if (startSavePoint != endSavePoint)
|
|
|
|
NotifySavePoint(endSavePoint);
|
2019-05-04 18:14:48 +00:00
|
|
|
|
2015-06-07 21:19:26 +00:00
|
|
|
cb.TentativeCommit();
|
|
|
|
}
|
|
|
|
enteredModification--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
int Document::UndoActions() const noexcept {
|
|
|
|
return cb.UndoActions();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::SetUndoSavePoint(int action) noexcept {
|
|
|
|
cb.SetUndoSavePoint(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Document::UndoSavePoint() const noexcept {
|
|
|
|
return cb.UndoSavePoint();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::SetUndoDetach(int action) noexcept {
|
|
|
|
cb.SetUndoDetach(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Document::UndoDetach() const noexcept {
|
|
|
|
return cb.UndoDetach();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::SetUndoTentative(int action) noexcept {
|
|
|
|
cb.SetUndoTentative(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Document::UndoTentative() const noexcept {
|
|
|
|
return cb.UndoTentative();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::SetUndoCurrent(int action) {
|
|
|
|
cb.SetUndoCurrent(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Document::UndoCurrent() const noexcept {
|
|
|
|
return cb.UndoCurrent();
|
|
|
|
}
|
|
|
|
|
|
|
|
int Document::UndoActionType(int action) const noexcept {
|
|
|
|
return cb.UndoActionType(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
Sci::Position Document::UndoActionPosition(int action) const noexcept {
|
|
|
|
return cb.UndoActionPosition(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string_view Document::UndoActionText(int action) const noexcept {
|
|
|
|
return cb.UndoActionText(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::PushUndoActionType(int type, Sci::Position position) {
|
|
|
|
cb.PushUndoActionType(type, position);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::ChangeLastUndoActionText(size_t length, const char *text) {
|
|
|
|
cb.ChangeLastUndoActionText(length, text);
|
|
|
|
}
|
|
|
|
|
2022-08-27 07:35:52 +00:00
|
|
|
int Document::GetMark(Sci::Line line, bool includeChangeHistory) const {
|
|
|
|
int marksHistory = 0;
|
|
|
|
if (includeChangeHistory && (line < LinesTotal())) {
|
|
|
|
int marksEdition = 0;
|
|
|
|
|
|
|
|
const Sci::Position start = LineStart(line);
|
|
|
|
const Sci::Position lineNext = LineStart(line + 1);
|
|
|
|
for (Sci::Position position = start; position < lineNext;) {
|
|
|
|
const int edition = EditionAt(position);
|
|
|
|
if (edition) {
|
|
|
|
marksEdition |= 1 << (edition-1);
|
|
|
|
}
|
|
|
|
position = EditionEndRun(position);
|
|
|
|
}
|
|
|
|
const Sci::Position lineEnd = LineEnd(line);
|
|
|
|
for (Sci::Position position = start; position <= lineEnd;) {
|
|
|
|
marksEdition |= EditionDeletesAt(position);
|
|
|
|
position = EditionNextDelete(position);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Bits: RevertedToOrigin, Saved, Modified, RevertedToModified */
|
|
|
|
constexpr unsigned int editionShift = static_cast<unsigned int>(MarkerOutline::HistoryRevertedToOrigin);
|
|
|
|
marksHistory = marksEdition << editionShift;
|
|
|
|
}
|
|
|
|
|
|
|
|
return marksHistory | Markers()->MarkValue(line);
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
Sci::Line Document::MarkerNext(Sci::Line lineStart, int mask) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
return Markers()->MarkerNext(lineStart, mask);
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
int Document::AddMark(Sci::Line line, int markerNum) {
|
2022-08-27 07:35:52 +00:00
|
|
|
if (line >= 0 && line < LinesTotal()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const int prev = Markers()->AddMark(line, markerNum, LinesTotal());
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeMarker, LineStart(line), 0, 0, nullptr, line);
|
2009-06-24 19:09:31 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
return prev;
|
|
|
|
} else {
|
2019-05-04 18:14:48 +00:00
|
|
|
return -1;
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::AddMarkSet(Sci::Line line, int valueSet) {
|
2022-08-27 07:35:52 +00:00
|
|
|
if (line < 0 || line >= LinesTotal()) {
|
2011-03-22 00:16:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
unsigned int m = valueSet;
|
2019-05-04 18:14:48 +00:00
|
|
|
for (int i = 0; m; i++, m >>= 1) {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (m & 1)
|
2019-05-04 18:14:48 +00:00
|
|
|
Markers()->AddMark(line, i, LinesTotal());
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeMarker, LineStart(line), 0, 0, nullptr, line);
|
2009-04-24 23:35:41 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::DeleteMark(Sci::Line line, int markerNum) {
|
|
|
|
Markers()->DeleteMark(line, markerNum, false);
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeMarker, LineStart(line), 0, 0, nullptr, line);
|
2009-04-24 23:35:41 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::DeleteMarkFromHandle(int markerHandle) {
|
2019-05-04 18:14:48 +00:00
|
|
|
Markers()->DeleteMarkFromHandle(markerHandle);
|
2022-01-04 23:07:50 +00:00
|
|
|
DocModification mh(ModificationFlags::ChangeMarker);
|
2009-04-24 23:35:41 +00:00
|
|
|
mh.line = -1;
|
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::DeleteAllMarks(int markerNum) {
|
2010-08-21 23:59:56 +00:00
|
|
|
bool someChanges = false;
|
2019-05-04 18:14:48 +00:00
|
|
|
for (Sci::Line line = 0; line < LinesTotal(); line++) {
|
|
|
|
if (Markers()->DeleteMark(line, markerNum, true))
|
2010-08-21 23:59:56 +00:00
|
|
|
someChanges = true;
|
|
|
|
}
|
|
|
|
if (someChanges) {
|
2022-01-04 23:07:50 +00:00
|
|
|
DocModification mh(ModificationFlags::ChangeMarker);
|
2010-08-21 23:59:56 +00:00
|
|
|
mh.line = -1;
|
|
|
|
NotifyModified(mh);
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
Sci::Line Document::LineFromHandle(int markerHandle) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
return Markers()->LineFromHandle(markerHandle);
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
int Document::MarkerNumberFromLine(Sci::Line line, int which) const noexcept {
|
|
|
|
return Markers()->NumberFromLine(line, which);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Document::MarkerHandleFromLine(Sci::Line line, int which) const noexcept {
|
|
|
|
return Markers()->HandleFromLine(line, which);
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci_Position SCI_METHOD Document::LineStart(Sci_Position line) const {
|
2021-02-21 04:53:09 +00:00
|
|
|
return cb.LineStart(line);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
Update scintilla 5.3.4 and lexilla 5.2.4 with:
https://www.scintilla.org/scintilla534.zip
Released 8 March 2023.
Add multithreaded wrap to significantly improve performance of wrapping large files.
More typesafe bindings of *Full APIs in ScintillaCall. Feature #1477.
Fix overlapping of text with line end wrap marker. Bug #2378.
Fix clipping of line end wrap symbol for SC_WRAPVISUALFLAGLOC_END_BY_TEXT.
Where a multi-byte character contains multiple styles, display each byte as a representation. This makes it easier to see and fix lexers that change styles mid-character, commonly because they use fixed size buffers.
Fix a potential crash with autocompletion list fill-ups where a SCN_CHARADDED handler retriggered an autocompletion list, but with no items that match the typed character.
lexilla523
Released 8 March 2023.
Add scripts/PromoteNew.bat script to promote .new files after checking.
Makefile: Remove 1024-byte line length limit..
Ruby: Add new lexical classes for % literals SCE_RB_STRING_W (%w non-interpolable string array), SCE_RB_STRING_I (%i non-interpolable symbol array), SCE_RB_STRING_QI (%I interpolable symbol array), and SCE_RB_STRING_QS (%s symbol). Issue #124.
Ruby: Disambiguate %= which may be a quote or modulo assignment. Issue #124, Bug #1255, Bug #2182.
Ruby: Fix additional fold level for single character in SCE_RB_STRING_QW. Issue #132.
Ruby: Set SCE_RB_HERE_QQ for unquoted and double-quoted heredocs and SCE_RB_HERE_QX for backticks-quoted heredocs. Issue #134.
Ruby: Recognise #{} inside SCE_RB_HERE_QQ and SCE_RB_HERE_QX. Issue #134.
Ruby: Improve regex and heredoc recognition. Issue #136.
Ruby: Highlight #@, #@@ and #$ style interpolation. Issue #140.
Ruby: Fix folding for multiple heredocs started on one line. Fix folding when there is a space after heredoc opening delimiter. Issue #135.
YAML: Remove 1024-byte line length limit.
https://www.scintilla.org/lexilla524.zip
Released 13 March 2023.
C++: Fix failure to recognize keywords containing upper case. Issue #149.
GDScript: Support % and $ node paths. Issue #145, Pull request #146.
Close #13338
2023-03-10 02:37:21 +00:00
|
|
|
Range Document::LineRange(Sci::Line line) const noexcept {
|
|
|
|
return {cb.LineStart(line), cb.LineStart(line + 1)};
|
|
|
|
}
|
|
|
|
|
2023-11-05 17:24:41 +00:00
|
|
|
bool Document::IsLineStartPosition(Sci::Position position) const noexcept {
|
|
|
|
return LineStartPosition(position) == position;
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci_Position SCI_METHOD Document::LineEnd(Sci_Position line) const {
|
2023-11-05 17:24:41 +00:00
|
|
|
return cb.LineEnd(line);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
int SCI_METHOD Document::DEVersion() const noexcept {
|
|
|
|
return deRelease0;
|
|
|
|
}
|
|
|
|
|
2010-08-21 23:59:56 +00:00
|
|
|
void SCI_METHOD Document::SetErrorStatus(int status) {
|
2013-08-28 00:44:27 +00:00
|
|
|
// Tell the watchers an error has occurred.
|
2019-05-04 18:14:48 +00:00
|
|
|
for (const WatcherWithUserData &watcher : watchers) {
|
2022-01-04 23:07:50 +00:00
|
|
|
watcher.watcher->NotifyErrorOccurred(this, watcher.userData, static_cast<Status>(status));
|
2010-08-21 23:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci_Position SCI_METHOD Document::LineFromPosition(Sci_Position pos) const {
|
|
|
|
return cb.LineFromPosition(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
Sci::Line Document::SciLineFromPosition(Sci::Position pos) const noexcept {
|
|
|
|
// Avoids casting in callers for this very common function
|
2009-04-24 23:35:41 +00:00
|
|
|
return cb.LineFromPosition(pos);
|
|
|
|
}
|
|
|
|
|
2023-11-05 17:24:41 +00:00
|
|
|
Sci::Position Document::LineStartPosition(Sci::Position position) const noexcept {
|
|
|
|
return cb.LineStart(cb.LineFromPosition(position));
|
|
|
|
}
|
|
|
|
|
|
|
|
Sci::Position Document::LineEndPosition(Sci::Position position) const noexcept {
|
|
|
|
return cb.LineEnd(cb.LineFromPosition(position));
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2023-11-05 17:24:41 +00:00
|
|
|
bool Document::IsLineEndPosition(Sci::Position position) const noexcept {
|
|
|
|
return LineEndPosition(position) == position;
|
2009-08-23 02:24:48 +00:00
|
|
|
}
|
|
|
|
|
2023-11-05 17:24:41 +00:00
|
|
|
bool Document::IsPositionInLineEnd(Sci::Position position) const noexcept {
|
|
|
|
return position >= LineEndPosition(position);
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::VCHomePosition(Sci::Position position) const {
|
|
|
|
const Sci::Line line = SciLineFromPosition(position);
|
|
|
|
const Sci::Position startPosition = LineStart(line);
|
|
|
|
const Sci::Position endLine = LineEnd(line);
|
|
|
|
Sci::Position startText = startPosition;
|
2023-02-09 16:57:24 +00:00
|
|
|
while (startText < endLine && IsSpaceOrTab(cb.CharAt(startText)))
|
2009-04-24 23:35:41 +00:00
|
|
|
startText++;
|
|
|
|
if (position == startText)
|
|
|
|
return startPosition;
|
|
|
|
else
|
|
|
|
return startText;
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
Sci::Position Document::IndexLineStart(Sci::Line line, LineCharacterIndexType lineCharacterIndex) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
return cb.IndexLineStart(line, lineCharacterIndex);
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
Sci::Line Document::LineFromPositionIndex(Sci::Position pos, LineCharacterIndexType lineCharacterIndex) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
return cb.LineFromPositionIndex(pos, lineCharacterIndex);
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
Sci::Line Document::LineFromPositionAfter(Sci::Line line, Sci::Position length) const noexcept {
|
|
|
|
const Sci::Position posAfter = cb.LineStart(line) + length;
|
|
|
|
if (posAfter >= LengthNoExcept()) {
|
|
|
|
return LinesTotal();
|
|
|
|
}
|
|
|
|
const Sci::Line lineAfter = SciLineFromPosition(posAfter);
|
|
|
|
if (lineAfter > line) {
|
|
|
|
return lineAfter;
|
|
|
|
} else {
|
|
|
|
// Want to make some progress so return next line
|
|
|
|
return lineAfter + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
int SCI_METHOD Document::SetLevel(Sci_Position line, int level) {
|
2021-02-21 04:53:09 +00:00
|
|
|
const int prev = Levels()->SetLevel(line, level, LinesTotal());
|
2009-04-24 23:35:41 +00:00
|
|
|
if (prev != level) {
|
2022-01-04 23:07:50 +00:00
|
|
|
DocModification mh(ModificationFlags::ChangeFold | ModificationFlags::ChangeMarker,
|
2021-02-21 04:53:09 +00:00
|
|
|
LineStart(line), 0, 0, nullptr, line);
|
2022-01-04 23:07:50 +00:00
|
|
|
mh.foldLevelNow = static_cast<FoldLevel>(level);
|
|
|
|
mh.foldLevelPrev = static_cast<FoldLevel>(prev);
|
2009-04-24 23:35:41 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
return prev;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
int SCI_METHOD Document::GetLevel(Sci_Position line) const {
|
2021-02-21 04:53:09 +00:00
|
|
|
return Levels()->GetLevel(line);
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2023-02-09 16:57:24 +00:00
|
|
|
FoldLevel Document::GetFoldLevel(Sci_Position line) const noexcept {
|
|
|
|
return Levels()->GetFoldLevel(line);
|
2022-01-04 23:07:50 +00:00
|
|
|
}
|
|
|
|
|
2010-07-12 22:19:51 +00:00
|
|
|
void Document::ClearLevels() {
|
2019-05-04 18:14:48 +00:00
|
|
|
Levels()->ClearLevels();
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
static bool IsSubordinate(FoldLevel levelStart, FoldLevel levelTry) noexcept {
|
|
|
|
if (LevelIsWhitespace(levelTry))
|
2009-04-24 23:35:41 +00:00
|
|
|
return true;
|
|
|
|
else
|
2019-05-04 18:14:48 +00:00
|
|
|
return LevelNumber(levelStart) < LevelNumber(levelTry);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
Sci::Line Document::GetLastChild(Sci::Line lineParent, std::optional<FoldLevel> level, Sci::Line lastLine) {
|
|
|
|
const FoldLevel levelStart = LevelNumberPart(level ? *level : GetFoldLevel(lineParent));
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line maxLine = LinesTotal();
|
|
|
|
const Sci::Line lookLastLine = (lastLine != -1) ? std::min(LinesTotal() - 1, lastLine) : -1;
|
|
|
|
Sci::Line lineMaxSubord = lineParent;
|
2009-04-24 23:35:41 +00:00
|
|
|
while (lineMaxSubord < maxLine - 1) {
|
|
|
|
EnsureStyledTo(LineStart(lineMaxSubord + 2));
|
2022-01-04 23:07:50 +00:00
|
|
|
if (!IsSubordinate(levelStart, GetFoldLevel(lineMaxSubord + 1)))
|
2009-04-24 23:35:41 +00:00
|
|
|
break;
|
2022-01-04 23:07:50 +00:00
|
|
|
if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !LevelIsWhitespace(GetFoldLevel(lineMaxSubord)))
|
2013-08-28 00:44:27 +00:00
|
|
|
break;
|
2009-04-24 23:35:41 +00:00
|
|
|
lineMaxSubord++;
|
|
|
|
}
|
|
|
|
if (lineMaxSubord > lineParent) {
|
2022-01-04 23:07:50 +00:00
|
|
|
if (levelStart > LevelNumberPart(GetFoldLevel(lineMaxSubord + 1))) {
|
2009-04-24 23:35:41 +00:00
|
|
|
// Have chewed up some whitespace that belongs to a parent so seek back
|
2022-01-04 23:07:50 +00:00
|
|
|
if (LevelIsWhitespace(GetFoldLevel(lineMaxSubord))) {
|
2009-04-24 23:35:41 +00:00
|
|
|
lineMaxSubord--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return lineMaxSubord;
|
|
|
|
}
|
|
|
|
|
2023-02-09 16:57:24 +00:00
|
|
|
Sci::Line Document::GetFoldParent(Sci::Line line) const noexcept {
|
|
|
|
return Levels()->GetFoldParent(line);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sci::Line line, Sci::Line lastLine) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const FoldLevel level = GetFoldLevel(line);
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line lookLastLine = std::max(line, lastLine) + 1;
|
2013-08-28 00:44:27 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Line lookLine = line;
|
2022-01-04 23:07:50 +00:00
|
|
|
FoldLevel lookLineLevel = level;
|
|
|
|
FoldLevel lookLineLevelNum = LevelNumberPart(lookLineLevel);
|
|
|
|
while ((lookLine > 0) && (LevelIsWhitespace(lookLineLevel) ||
|
|
|
|
(LevelIsHeader(lookLineLevel) && (lookLineLevelNum >= LevelNumberPart(GetFoldLevel(lookLine + 1)))))) {
|
|
|
|
lookLineLevel = GetFoldLevel(--lookLine);
|
|
|
|
lookLineLevelNum = LevelNumberPart(lookLineLevel);
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
Sci::Line beginFoldBlock = LevelIsHeader(lookLineLevel) ? lookLine : GetFoldParent(lookLine);
|
2013-08-28 00:44:27 +00:00
|
|
|
if (beginFoldBlock == -1) {
|
|
|
|
highlightDelimiter.Clear();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
Sci::Line endFoldBlock = GetLastChild(beginFoldBlock, {}, lookLastLine);
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Line firstChangeableLineBefore = -1;
|
2013-08-28 00:44:27 +00:00
|
|
|
if (endFoldBlock < line) {
|
|
|
|
lookLine = beginFoldBlock - 1;
|
2022-01-04 23:07:50 +00:00
|
|
|
lookLineLevel = GetFoldLevel(lookLine);
|
|
|
|
lookLineLevelNum = LevelNumberPart(lookLineLevel);
|
|
|
|
while ((lookLine >= 0) && (lookLineLevelNum >= FoldLevel::Base)) {
|
|
|
|
if (LevelIsHeader(lookLineLevel)) {
|
|
|
|
if (GetLastChild(lookLine, {}, lookLastLine) == line) {
|
2013-08-28 00:44:27 +00:00
|
|
|
beginFoldBlock = lookLine;
|
|
|
|
endFoldBlock = line;
|
|
|
|
firstChangeableLineBefore = line - 1;
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
if ((lookLine > 0) && (lookLineLevelNum == FoldLevel::Base) && (LevelNumberPart(GetFoldLevel(lookLine - 1)) > lookLineLevelNum))
|
2013-08-28 00:44:27 +00:00
|
|
|
break;
|
2022-01-04 23:07:50 +00:00
|
|
|
lookLineLevel = GetFoldLevel(--lookLine);
|
|
|
|
lookLineLevelNum = LevelNumberPart(lookLineLevel);
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
if (firstChangeableLineBefore == -1) {
|
2022-01-04 23:07:50 +00:00
|
|
|
for (lookLine = line - 1, lookLineLevel = GetFoldLevel(lookLine), lookLineLevelNum = LevelNumberPart(lookLineLevel);
|
2013-08-28 00:44:27 +00:00
|
|
|
lookLine >= beginFoldBlock;
|
2022-01-04 23:07:50 +00:00
|
|
|
lookLineLevel = GetFoldLevel(--lookLine), lookLineLevelNum = LevelNumberPart(lookLineLevel)) {
|
|
|
|
if (LevelIsWhitespace(lookLineLevel) || (lookLineLevelNum > LevelNumberPart(level))) {
|
2013-08-28 00:44:27 +00:00
|
|
|
firstChangeableLineBefore = lookLine;
|
|
|
|
break;
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
if (firstChangeableLineBefore == -1)
|
|
|
|
firstChangeableLineBefore = beginFoldBlock - 1;
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Line firstChangeableLineAfter = -1;
|
2022-01-04 23:07:50 +00:00
|
|
|
for (lookLine = line + 1, lookLineLevel = GetFoldLevel(lookLine), lookLineLevelNum = LevelNumberPart(lookLineLevel);
|
2013-08-28 00:44:27 +00:00
|
|
|
lookLine <= endFoldBlock;
|
2022-01-04 23:07:50 +00:00
|
|
|
lookLineLevel = GetFoldLevel(++lookLine), lookLineLevelNum = LevelNumberPart(lookLineLevel)) {
|
|
|
|
if (LevelIsHeader(lookLineLevel) && (lookLineLevelNum < LevelNumberPart(GetFoldLevel(lookLine + 1)))) {
|
2013-08-28 00:44:27 +00:00
|
|
|
firstChangeableLineAfter = lookLine;
|
|
|
|
break;
|
|
|
|
}
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
if (firstChangeableLineAfter == -1)
|
|
|
|
firstChangeableLineAfter = endFoldBlock + 1;
|
2011-07-17 22:30:49 +00:00
|
|
|
|
|
|
|
highlightDelimiter.beginFoldBlock = beginFoldBlock;
|
|
|
|
highlightDelimiter.endFoldBlock = endFoldBlock;
|
2013-08-28 00:44:27 +00:00
|
|
|
highlightDelimiter.firstChangeableLineBefore = firstChangeableLineBefore;
|
|
|
|
highlightDelimiter.firstChangeableLineAfter = firstChangeableLineAfter;
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
Sci::Position Document::ClampPositionIntoDocument(Sci::Position pos) const noexcept {
|
|
|
|
return std::clamp<Sci::Position>(pos, 0, LengthNoExcept());
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
bool Document::IsCrLf(Sci::Position pos) const noexcept {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (pos < 0)
|
|
|
|
return false;
|
2019-07-21 13:26:02 +00:00
|
|
|
if (pos >= (LengthNoExcept() - 1))
|
2009-04-24 23:35:41 +00:00
|
|
|
return false;
|
|
|
|
return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n');
|
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
int Document::LenChar(Sci::Position pos) const noexcept {
|
|
|
|
if (pos < 0 || pos >= LengthNoExcept()) {
|
|
|
|
// Returning 1 instead of 0 to defend against hanging with a loop that goes (or starts) out of bounds.
|
2009-04-24 23:35:41 +00:00
|
|
|
return 1;
|
|
|
|
} else if (IsCrLf(pos)) {
|
|
|
|
return 2;
|
2019-07-21 13:26:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const unsigned char leadByte = cb.UCharAt(pos);
|
|
|
|
if (!dbcsCodePage || UTF8IsAscii(leadByte)) {
|
|
|
|
// Common case: ASCII character
|
|
|
|
return 1;
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
if (CpUtf8 == dbcsCodePage) {
|
2013-08-28 00:44:27 +00:00
|
|
|
const int widthCharBytes = UTF8BytesOfLead[leadByte];
|
2019-07-21 13:26:02 +00:00
|
|
|
unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 };
|
|
|
|
for (int b = 1; b < widthCharBytes; b++) {
|
|
|
|
charBytes[b] = cb.UCharAt(pos + b);
|
|
|
|
}
|
|
|
|
const int utf8status = UTF8Classify(charBytes, widthCharBytes);
|
|
|
|
if (utf8status & UTF8MaskInvalid) {
|
|
|
|
// Treat as invalid and use up just one byte
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return utf8status & UTF8MaskWidth;
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
} else {
|
2022-01-04 23:07:50 +00:00
|
|
|
if (IsDBCSLeadByteNoExcept(leadByte) && IsDBCSTrailByteNoExcept(cb.CharAt(pos + 1))) {
|
2019-07-21 13:26:02 +00:00
|
|
|
return 2;
|
|
|
|
} else {
|
|
|
|
return 1;
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
bool Document::InGoodUTF8(Sci::Position pos, Sci::Position &start, Sci::Position &end) const noexcept {
|
|
|
|
Sci::Position trail = pos;
|
|
|
|
while ((trail>0) && (pos-trail < UTF8MaxBytes) && UTF8IsTrailByte(cb.UCharAt(trail-1)))
|
2013-08-28 00:44:27 +00:00
|
|
|
trail--;
|
|
|
|
start = (trail > 0) ? trail-1 : trail;
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
const unsigned char leadByte = cb.UCharAt(start);
|
2013-08-28 00:44:27 +00:00
|
|
|
const int widthCharBytes = UTF8BytesOfLead[leadByte];
|
|
|
|
if (widthCharBytes == 1) {
|
2009-04-24 23:35:41 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
2019-05-04 18:14:48 +00:00
|
|
|
const int trailBytes = widthCharBytes - 1;
|
|
|
|
const Sci::Position len = pos - start;
|
2009-04-24 23:35:41 +00:00
|
|
|
if (len > trailBytes)
|
|
|
|
// pos too far from lead
|
|
|
|
return false;
|
2019-05-04 18:14:48 +00:00
|
|
|
unsigned char charBytes[UTF8MaxBytes] = {leadByte,0,0,0};
|
|
|
|
for (Sci::Position b=1; b<widthCharBytes && ((start+b) < cb.Length()); b++)
|
|
|
|
charBytes[b] = cb.CharAt(start+b);
|
|
|
|
const int utf8status = UTF8Classify(charBytes, widthCharBytes);
|
2013-08-28 00:44:27 +00:00
|
|
|
if (utf8status & UTF8MaskInvalid)
|
|
|
|
return false;
|
|
|
|
end = start + widthCharBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
// Normalise a position so that it is not part way through a multi-byte character.
|
2009-04-24 23:35:41 +00:00
|
|
|
// This can occur in two situations -
|
|
|
|
// When lines are terminated with \r\n pairs which should be treated as one character.
|
|
|
|
// When displaying DBCS text such as Japanese.
|
|
|
|
// If moving, move the position in the indicated direction.
|
2019-07-21 13:26:02 +00:00
|
|
|
Sci::Position Document::MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd) const noexcept {
|
2009-04-24 23:35:41 +00:00
|
|
|
//Platform::DebugPrintf("NoCRLF %d %d\n", pos, moveDir);
|
|
|
|
// If out of range, just return minimum/maximum value.
|
|
|
|
if (pos <= 0)
|
|
|
|
return 0;
|
2019-07-21 13:26:02 +00:00
|
|
|
if (pos >= LengthNoExcept())
|
|
|
|
return LengthNoExcept();
|
2009-04-24 23:35:41 +00:00
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
// PLATFORM_ASSERT(pos > 0 && pos < LengthNoExcept());
|
2009-04-24 23:35:41 +00:00
|
|
|
if (checkLineEnd && IsCrLf(pos - 1)) {
|
|
|
|
if (moveDir > 0)
|
|
|
|
return pos + 1;
|
|
|
|
else
|
|
|
|
return pos - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dbcsCodePage) {
|
2022-01-04 23:07:50 +00:00
|
|
|
if (CpUtf8 == dbcsCodePage) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const unsigned char ch = cb.UCharAt(pos);
|
2013-08-28 00:44:27 +00:00
|
|
|
// If ch is not a trail byte then pos is valid intercharacter position
|
|
|
|
if (UTF8IsTrailByte(ch)) {
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position startUTF = pos;
|
|
|
|
Sci::Position endUTF = pos;
|
2013-08-28 00:44:27 +00:00
|
|
|
if (InGoodUTF8(pos, startUTF, endUTF)) {
|
|
|
|
// ch is a trail byte within a UTF-8 character
|
|
|
|
if (moveDir > 0)
|
|
|
|
pos = endUTF;
|
|
|
|
else
|
|
|
|
pos = startUTF;
|
|
|
|
}
|
|
|
|
// Else invalid UTF-8 so return position of isolated trail byte
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Anchor DBCS calculations at start of line because start of line can
|
|
|
|
// not be a DBCS trail byte.
|
2023-11-05 17:24:41 +00:00
|
|
|
const Sci::Position posStartLine = LineStartPosition(pos);
|
2010-09-05 22:56:27 +00:00
|
|
|
if (pos == posStartLine)
|
|
|
|
return pos;
|
2009-04-24 23:35:41 +00:00
|
|
|
|
2010-09-05 22:56:27 +00:00
|
|
|
// Step back until a non-lead-byte is found.
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position posCheck = pos;
|
|
|
|
while ((posCheck > posStartLine) && IsDBCSLeadByteNoExcept(cb.CharAt(posCheck-1)))
|
2010-09-05 22:56:27 +00:00
|
|
|
posCheck--;
|
|
|
|
|
|
|
|
// Check from known start of character.
|
|
|
|
while (posCheck < pos) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const int mbsize = IsDBCSDualByteAt(posCheck) ? 2 : 1;
|
2009-04-24 23:35:41 +00:00
|
|
|
if (posCheck + mbsize == pos) {
|
|
|
|
return pos;
|
|
|
|
} else if (posCheck + mbsize > pos) {
|
|
|
|
if (moveDir > 0) {
|
|
|
|
return posCheck + mbsize;
|
|
|
|
} else {
|
|
|
|
return posCheck;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
posCheck += mbsize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2010-09-05 22:56:27 +00:00
|
|
|
// NextPosition moves between valid positions - it can not handle a position in the middle of a
|
|
|
|
// multi-byte character. It is used to iterate through text more efficiently than MovePositionOutsideChar.
|
|
|
|
// A \r\n pair is treated as two characters.
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const noexcept {
|
2010-09-05 22:56:27 +00:00
|
|
|
// If out of range, just return minimum/maximum value.
|
2019-05-04 18:14:48 +00:00
|
|
|
const int increment = (moveDir > 0) ? 1 : -1;
|
2010-09-05 22:56:27 +00:00
|
|
|
if (pos + increment <= 0)
|
|
|
|
return 0;
|
2019-05-04 18:14:48 +00:00
|
|
|
if (pos + increment >= cb.Length())
|
|
|
|
return cb.Length();
|
2010-09-05 22:56:27 +00:00
|
|
|
|
|
|
|
if (dbcsCodePage) {
|
2022-01-04 23:07:50 +00:00
|
|
|
if (CpUtf8 == dbcsCodePage) {
|
2013-08-28 00:44:27 +00:00
|
|
|
if (increment == 1) {
|
|
|
|
// Simple forward movement case so can avoid some checks
|
2019-05-04 18:14:48 +00:00
|
|
|
const unsigned char leadByte = cb.UCharAt(pos);
|
2013-08-28 00:44:27 +00:00
|
|
|
if (UTF8IsAscii(leadByte)) {
|
|
|
|
// Single byte character or invalid
|
|
|
|
pos++;
|
|
|
|
} else {
|
|
|
|
const int widthCharBytes = UTF8BytesOfLead[leadByte];
|
2019-05-04 18:14:48 +00:00
|
|
|
unsigned char charBytes[UTF8MaxBytes] = {leadByte,0,0,0};
|
2013-08-28 00:44:27 +00:00
|
|
|
for (int b=1; b<widthCharBytes; b++)
|
2019-05-04 18:14:48 +00:00
|
|
|
charBytes[b] = cb.CharAt(pos+b);
|
|
|
|
const int utf8status = UTF8Classify(charBytes, widthCharBytes);
|
2013-08-28 00:44:27 +00:00
|
|
|
if (utf8status & UTF8MaskInvalid)
|
|
|
|
pos++;
|
|
|
|
else
|
|
|
|
pos += utf8status & UTF8MaskWidth;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Examine byte before position
|
|
|
|
pos--;
|
2019-05-04 18:14:48 +00:00
|
|
|
const unsigned char ch = cb.UCharAt(pos);
|
2013-08-28 00:44:27 +00:00
|
|
|
// If ch is not a trail byte then pos is valid intercharacter position
|
|
|
|
if (UTF8IsTrailByte(ch)) {
|
|
|
|
// If ch is a trail byte in a valid UTF-8 character then return start of character
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position startUTF = pos;
|
|
|
|
Sci::Position endUTF = pos;
|
2013-08-28 00:44:27 +00:00
|
|
|
if (InGoodUTF8(pos, startUTF, endUTF)) {
|
|
|
|
pos = startUTF;
|
|
|
|
}
|
|
|
|
// Else invalid UTF-8 so return position of isolated trail byte
|
|
|
|
}
|
2010-09-05 22:56:27 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (moveDir > 0) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const int mbsize = IsDBCSDualByteAt(pos) ? 2 : 1;
|
2010-09-05 22:56:27 +00:00
|
|
|
pos += mbsize;
|
2019-05-04 18:14:48 +00:00
|
|
|
if (pos > cb.Length())
|
|
|
|
pos = cb.Length();
|
2010-09-05 22:56:27 +00:00
|
|
|
} else {
|
|
|
|
// Anchor DBCS calculations at start of line because start of line can
|
|
|
|
// not be a DBCS trail byte.
|
2023-11-05 17:24:41 +00:00
|
|
|
const Sci::Position posStartLine = LineStartPosition(pos);
|
2010-09-05 22:56:27 +00:00
|
|
|
// See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx
|
|
|
|
// http://msdn.microsoft.com/en-us/library/cc194790.aspx
|
|
|
|
if ((pos - 1) <= posStartLine) {
|
2010-11-09 19:27:26 +00:00
|
|
|
return pos - 1;
|
2019-05-04 18:14:48 +00:00
|
|
|
} else if (IsDBCSLeadByteNoExcept(cb.CharAt(pos - 1))) {
|
2022-01-04 23:07:50 +00:00
|
|
|
// Should actually be trail byte
|
|
|
|
if (IsDBCSDualByteAt(pos - 2)) {
|
|
|
|
return pos - 2;
|
|
|
|
} else {
|
|
|
|
// Invalid byte pair so treat as one byte wide
|
|
|
|
return pos - 1;
|
|
|
|
}
|
2010-09-05 22:56:27 +00:00
|
|
|
} else {
|
|
|
|
// Otherwise, step back until a non-lead-byte is found.
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position posTemp = pos - 1;
|
|
|
|
while (posStartLine <= --posTemp && IsDBCSLeadByteNoExcept(cb.CharAt(posTemp)))
|
2010-09-05 22:56:27 +00:00
|
|
|
;
|
|
|
|
// Now posTemp+1 must point to the beginning of a character,
|
|
|
|
// so figure out whether we went back an even or an odd
|
|
|
|
// number of bytes and go back 1 or 2 bytes, respectively.
|
2022-01-04 23:07:50 +00:00
|
|
|
const Sci::Position widthLast = ((pos - posTemp) & 1) + 1;
|
|
|
|
if ((widthLast == 2) && (IsDBCSDualByteAt(pos - widthLast))) {
|
|
|
|
return pos - widthLast;
|
|
|
|
}
|
|
|
|
// Byte before pos may be valid character or may be an invalid second byte
|
|
|
|
return pos - 1;
|
2010-09-05 22:56:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pos += increment;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
bool Document::NextCharacter(Sci::Position &pos, int moveDir) const noexcept {
|
2010-09-05 22:56:27 +00:00
|
|
|
// Returns true if pos changed
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position posNext = NextPosition(pos, moveDir);
|
2010-09-05 22:56:27 +00:00
|
|
|
if (posNext == pos) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
pos = posNext;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-10 12:35:16 +00:00
|
|
|
CharacterExtracted Document::CharacterAfter(Sci::Position position) const noexcept {
|
2019-07-21 13:26:02 +00:00
|
|
|
if (position >= LengthNoExcept()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
return CharacterExtracted(unicodeReplacementChar, 0);
|
|
|
|
}
|
|
|
|
const unsigned char leadByte = cb.UCharAt(position);
|
|
|
|
if (!dbcsCodePage || UTF8IsAscii(leadByte)) {
|
|
|
|
// Common case: ASCII character
|
|
|
|
return CharacterExtracted(leadByte, 1);
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
if (CpUtf8 == dbcsCodePage) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const int widthCharBytes = UTF8BytesOfLead[leadByte];
|
|
|
|
unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 };
|
|
|
|
for (int b = 1; b<widthCharBytes; b++)
|
|
|
|
charBytes[b] = cb.UCharAt(position + b);
|
2022-12-10 12:35:16 +00:00
|
|
|
return CharacterExtracted(charBytes, widthCharBytes);
|
2019-05-04 18:14:48 +00:00
|
|
|
} else {
|
2022-01-04 23:07:50 +00:00
|
|
|
if (IsDBCSLeadByteNoExcept(leadByte)) {
|
|
|
|
const unsigned char trailByte = cb.UCharAt(position + 1);
|
|
|
|
if (IsDBCSTrailByteNoExcept(trailByte)) {
|
|
|
|
return CharacterExtracted::DBCS(leadByte, trailByte);
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
return CharacterExtracted(leadByte, 1);
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-10 12:35:16 +00:00
|
|
|
CharacterExtracted Document::CharacterBefore(Sci::Position position) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
if (position <= 0) {
|
|
|
|
return CharacterExtracted(unicodeReplacementChar, 0);
|
|
|
|
}
|
|
|
|
const unsigned char previousByte = cb.UCharAt(position - 1);
|
|
|
|
if (0 == dbcsCodePage) {
|
|
|
|
return CharacterExtracted(previousByte, 1);
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
if (CpUtf8 == dbcsCodePage) {
|
2019-05-04 18:14:48 +00:00
|
|
|
if (UTF8IsAscii(previousByte)) {
|
|
|
|
return CharacterExtracted(previousByte, 1);
|
|
|
|
}
|
|
|
|
position--;
|
|
|
|
// If previousByte is not a trail byte then its invalid
|
|
|
|
if (UTF8IsTrailByte(previousByte)) {
|
|
|
|
// If previousByte is a trail byte in a valid UTF-8 character then find start of character
|
|
|
|
Sci::Position startUTF = position;
|
|
|
|
Sci::Position endUTF = position;
|
|
|
|
if (InGoodUTF8(position, startUTF, endUTF)) {
|
2021-02-21 04:53:09 +00:00
|
|
|
const Sci::Position widthCharBytes = endUTF - startUTF;
|
2019-05-04 18:14:48 +00:00
|
|
|
unsigned char charBytes[UTF8MaxBytes] = { 0, 0, 0, 0 };
|
2021-02-21 04:53:09 +00:00
|
|
|
for (Sci::Position b = 0; b<widthCharBytes; b++)
|
2019-05-04 18:14:48 +00:00
|
|
|
charBytes[b] = cb.UCharAt(startUTF + b);
|
2022-12-10 12:35:16 +00:00
|
|
|
return CharacterExtracted(charBytes, widthCharBytes);
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
// Else invalid UTF-8 so return position of isolated trail byte
|
|
|
|
}
|
|
|
|
return CharacterExtracted(unicodeReplacementChar, 1);
|
|
|
|
} else {
|
|
|
|
// Moving backwards in DBCS is complex so use NextPosition
|
|
|
|
const Sci::Position posStartCharacter = NextPosition(position, -1);
|
|
|
|
return CharacterAfter(posStartCharacter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-07 21:19:26 +00:00
|
|
|
// Return -1 on out-of-bounds
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci_Position SCI_METHOD Document::GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const {
|
|
|
|
Sci::Position pos = positionStart;
|
2015-06-07 21:19:26 +00:00
|
|
|
if (dbcsCodePage) {
|
|
|
|
const int increment = (characterOffset > 0) ? 1 : -1;
|
|
|
|
while (characterOffset != 0) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position posNext = NextPosition(pos, increment);
|
2015-06-07 21:19:26 +00:00
|
|
|
if (posNext == pos)
|
2022-01-04 23:07:50 +00:00
|
|
|
return Sci::invalidPosition;
|
2015-06-07 21:19:26 +00:00
|
|
|
pos = posNext;
|
|
|
|
characterOffset -= increment;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pos = positionStart + characterOffset;
|
|
|
|
if ((pos < 0) || (pos > Length()))
|
2022-01-04 23:07:50 +00:00
|
|
|
return Sci::invalidPosition;
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
2015-06-07 21:19:26 +00:00
|
|
|
return pos;
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
Sci::Position Document::GetRelativePositionUTF16(Sci::Position positionStart, Sci::Position characterOffset) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position pos = positionStart;
|
2013-08-28 00:44:27 +00:00
|
|
|
if (dbcsCodePage) {
|
|
|
|
const int increment = (characterOffset > 0) ? 1 : -1;
|
|
|
|
while (characterOffset != 0) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position posNext = NextPosition(pos, increment);
|
2013-08-28 00:44:27 +00:00
|
|
|
if (posNext == pos)
|
2022-01-04 23:07:50 +00:00
|
|
|
return Sci::invalidPosition;
|
2019-05-04 18:14:48 +00:00
|
|
|
if (std::abs(pos-posNext) > 3) // 4 byte character = 2*UTF16.
|
2015-06-07 21:19:26 +00:00
|
|
|
characterOffset -= increment;
|
2013-08-28 00:44:27 +00:00
|
|
|
pos = posNext;
|
|
|
|
characterOffset -= increment;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pos = positionStart + characterOffset;
|
2019-07-21 13:26:02 +00:00
|
|
|
if ((pos < 0) || (pos > LengthNoExcept()))
|
2022-01-04 23:07:50 +00:00
|
|
|
return Sci::invalidPosition;
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
int SCI_METHOD Document::GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const {
|
2013-08-28 00:44:27 +00:00
|
|
|
int bytesInCharacter = 1;
|
2019-05-04 18:14:48 +00:00
|
|
|
const unsigned char leadByte = cb.UCharAt(position);
|
2022-01-04 23:07:50 +00:00
|
|
|
int character = leadByte;
|
|
|
|
if (dbcsCodePage && !UTF8IsAscii(leadByte)) {
|
|
|
|
if (CpUtf8 == dbcsCodePage) {
|
|
|
|
const int widthCharBytes = UTF8BytesOfLead[leadByte];
|
|
|
|
unsigned char charBytes[UTF8MaxBytes] = {leadByte,0,0,0};
|
|
|
|
for (int b=1; b<widthCharBytes; b++)
|
|
|
|
charBytes[b] = cb.UCharAt(position+b);
|
|
|
|
const int utf8status = UTF8Classify(charBytes, widthCharBytes);
|
|
|
|
if (utf8status & UTF8MaskInvalid) {
|
|
|
|
// Report as singleton surrogate values which are invalid Unicode
|
|
|
|
character = 0xDC80 + leadByte;
|
2013-08-28 00:44:27 +00:00
|
|
|
} else {
|
2022-01-04 23:07:50 +00:00
|
|
|
bytesInCharacter = utf8status & UTF8MaskWidth;
|
|
|
|
character = UnicodeFromUTF8(charBytes);
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
} else {
|
2019-05-04 18:14:48 +00:00
|
|
|
if (IsDBCSLeadByteNoExcept(leadByte)) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const unsigned char trailByte = cb.UCharAt(position + 1);
|
|
|
|
if (IsDBCSTrailByteNoExcept(trailByte)) {
|
|
|
|
bytesInCharacter = 2;
|
|
|
|
character = (leadByte << 8) | trailByte;
|
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pWidth) {
|
|
|
|
*pWidth = bytesInCharacter;
|
|
|
|
}
|
|
|
|
return character;
|
|
|
|
}
|
|
|
|
|
2010-08-21 23:59:56 +00:00
|
|
|
int SCI_METHOD Document::CodePage() const {
|
|
|
|
return dbcsCodePage;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
|
2019-05-04 18:14:48 +00:00
|
|
|
// Used by lexers so must match IDocument method exactly
|
|
|
|
return IsDBCSLeadByteNoExcept(ch);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Document::IsDBCSLeadByteNoExcept(char ch) const noexcept {
|
|
|
|
// Used inside core Scintilla
|
2010-09-05 22:56:27 +00:00
|
|
|
// Byte ranges found in Wikipedia articles with relevant search strings in each case
|
2019-05-04 18:14:48 +00:00
|
|
|
const unsigned char uch = ch;
|
2010-09-05 22:56:27 +00:00
|
|
|
switch (dbcsCodePage) {
|
|
|
|
case 932:
|
|
|
|
// Shift_jis
|
|
|
|
return ((uch >= 0x81) && (uch <= 0x9F)) ||
|
2013-08-28 00:44:27 +00:00
|
|
|
((uch >= 0xE0) && (uch <= 0xFC));
|
|
|
|
// Lead bytes F0 to FC may be a Microsoft addition.
|
2010-09-05 22:56:27 +00:00
|
|
|
case 936:
|
|
|
|
// GBK
|
|
|
|
return (uch >= 0x81) && (uch <= 0xFE);
|
|
|
|
case 949:
|
|
|
|
// Korean Wansung KS C-5601-1987
|
|
|
|
return (uch >= 0x81) && (uch <= 0xFE);
|
|
|
|
case 950:
|
|
|
|
// Big5
|
|
|
|
return (uch >= 0x81) && (uch <= 0xFE);
|
|
|
|
case 1361:
|
|
|
|
// Korean Johab KS C-5601-1992
|
|
|
|
return
|
|
|
|
((uch >= 0x84) && (uch <= 0xD3)) ||
|
|
|
|
((uch >= 0xD8) && (uch <= 0xDE)) ||
|
|
|
|
((uch >= 0xE0) && (uch <= 0xF9));
|
|
|
|
}
|
|
|
|
return false;
|
2010-08-21 23:59:56 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
bool Document::IsDBCSTrailByteNoExcept(char ch) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
const unsigned char trail = ch;
|
|
|
|
switch (dbcsCodePage) {
|
|
|
|
case 932:
|
|
|
|
// Shift_jis
|
2022-01-04 23:07:50 +00:00
|
|
|
return (trail != 0x7F) &&
|
|
|
|
((trail >= 0x40) && (trail <= 0xFC));
|
2019-05-04 18:14:48 +00:00
|
|
|
case 936:
|
|
|
|
// GBK
|
2022-01-04 23:07:50 +00:00
|
|
|
return (trail != 0x7F) &&
|
|
|
|
((trail >= 0x40) && (trail <= 0xFE));
|
2019-05-04 18:14:48 +00:00
|
|
|
case 949:
|
|
|
|
// Korean Wansung KS C-5601-1987
|
|
|
|
return
|
2022-01-04 23:07:50 +00:00
|
|
|
((trail >= 0x41) && (trail <= 0x5A)) ||
|
|
|
|
((trail >= 0x61) && (trail <= 0x7A)) ||
|
|
|
|
((trail >= 0x81) && (trail <= 0xFE));
|
2019-05-04 18:14:48 +00:00
|
|
|
case 950:
|
|
|
|
// Big5
|
|
|
|
return
|
2022-01-04 23:07:50 +00:00
|
|
|
((trail >= 0x40) && (trail <= 0x7E)) ||
|
|
|
|
((trail >= 0xA1) && (trail <= 0xFE));
|
2019-05-04 18:14:48 +00:00
|
|
|
case 1361:
|
|
|
|
// Korean Johab KS C-5601-1992
|
|
|
|
return
|
2022-01-04 23:07:50 +00:00
|
|
|
((trail >= 0x31) && (trail <= 0x7E)) ||
|
|
|
|
((trail >= 0x81) && (trail <= 0xFE));
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Document::DBCSDrawBytes(std::string_view text) const noexcept {
|
|
|
|
if (text.length() <= 1) {
|
|
|
|
return static_cast<int>(text.length());
|
|
|
|
}
|
|
|
|
if (IsDBCSLeadByteNoExcept(text[0])) {
|
2022-01-04 23:07:50 +00:00
|
|
|
return IsDBCSTrailByteNoExcept(text[1]) ? 2 : 1;
|
2019-05-04 18:14:48 +00:00
|
|
|
} else {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
bool Document::IsDBCSDualByteAt(Sci::Position pos) const noexcept {
|
|
|
|
return IsDBCSLeadByteNoExcept(cb.CharAt(pos))
|
|
|
|
&& IsDBCSTrailByteNoExcept(cb.CharAt(pos + 1));
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
// Need to break text into segments near end but taking into account the
|
|
|
|
// encoding to not break inside a UTF-8 or DBCS character and also trying
|
|
|
|
// to avoid breaking inside a pair of combining characters, or inside
|
|
|
|
// ligatures.
|
|
|
|
// TODO: implement grapheme cluster boundaries,
|
|
|
|
// see https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries.
|
|
|
|
//
|
2011-07-17 22:30:49 +00:00
|
|
|
// The segment length must always be long enough (more than 4 bytes)
|
|
|
|
// so that there will be at least one whole character to make a segment.
|
|
|
|
// For UTF-8, text must consist only of valid whole characters.
|
|
|
|
// In preference order from best to worst:
|
2022-01-04 23:07:50 +00:00
|
|
|
// 1) Break before or after spaces or controls
|
|
|
|
// 2) Break at word and punctuation boundary for better kerning and ligature support
|
|
|
|
// 3) Break after whole character, this may break combining characters
|
|
|
|
|
|
|
|
size_t Document::SafeSegment(std::string_view text) const noexcept {
|
|
|
|
// check space first as most written language use spaces.
|
|
|
|
for (std::string_view::iterator it = text.end() - 1; it != text.begin(); --it) {
|
|
|
|
if (IsBreakSpace(*it)) {
|
|
|
|
return it - text.begin();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dbcsCodePage || dbcsCodePage == CpUtf8) {
|
|
|
|
// backward iterate for UTF-8 and single byte encoding to find word and punctuation boundary.
|
|
|
|
std::string_view::iterator it = text.end() - 1;
|
|
|
|
const bool punctuation = IsPunctuation(*it);
|
|
|
|
do {
|
|
|
|
--it;
|
|
|
|
if (punctuation != IsPunctuation(*it)) {
|
|
|
|
return it - text.begin() + 1;
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
} while (it != text.begin());
|
|
|
|
|
|
|
|
it = text.end() - 1;
|
|
|
|
if (dbcsCodePage) {
|
|
|
|
// for UTF-8 go back to the start of last character.
|
|
|
|
for (int trail = 0; trail < UTF8MaxBytes - 1 && UTF8IsTrailByte(*it); trail++) {
|
|
|
|
--it;
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
return it - text.begin();
|
|
|
|
}
|
2011-07-17 22:30:49 +00:00
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
{
|
|
|
|
// forward iterate for DBCS to find word and punctuation boundary.
|
|
|
|
size_t lastPunctuationBreak = 0;
|
|
|
|
size_t lastEncodingAllowedBreak = 0;
|
|
|
|
CharacterClass ccPrev = CharacterClass::space;
|
|
|
|
for (size_t j = 0; j < text.length();) {
|
|
|
|
const unsigned char ch = text[j];
|
|
|
|
lastEncodingAllowedBreak = j++;
|
|
|
|
|
|
|
|
CharacterClass cc = CharacterClass::word;
|
|
|
|
if (UTF8IsAscii(ch)) {
|
|
|
|
if (IsPunctuation(ch)) {
|
|
|
|
cc = CharacterClass::punctuation;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
j += IsDBCSLeadByteNoExcept(ch);
|
|
|
|
}
|
|
|
|
if (cc != ccPrev) {
|
|
|
|
ccPrev = cc;
|
|
|
|
lastPunctuationBreak = lastEncodingAllowedBreak;
|
|
|
|
}
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
return lastPunctuationBreak ? lastPunctuationBreak : lastEncodingAllowedBreak;
|
2011-07-17 22:30:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
EncodingFamily Document::CodePageFamily() const noexcept {
|
2022-01-04 23:07:50 +00:00
|
|
|
if (CpUtf8 == dbcsCodePage)
|
2021-02-21 04:53:09 +00:00
|
|
|
return EncodingFamily::unicode;
|
2015-06-07 21:19:26 +00:00
|
|
|
else if (dbcsCodePage)
|
2021-02-21 04:53:09 +00:00
|
|
|
return EncodingFamily::dbcs;
|
2015-06-07 21:19:26 +00:00
|
|
|
else
|
2021-02-21 04:53:09 +00:00
|
|
|
return EncodingFamily::eightBit;
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::ModifiedAt(Sci::Position pos) noexcept {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (endStyled > pos)
|
|
|
|
endStyled = pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::CheckReadOnly() {
|
|
|
|
if (cb.IsReadOnly() && enteredReadOnlyCount == 0) {
|
|
|
|
enteredReadOnlyCount++;
|
|
|
|
NotifyModifyAttempt();
|
|
|
|
enteredReadOnlyCount--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-10 12:35:16 +00:00
|
|
|
void Document::TrimReplacement(std::string_view &text, Range &range) const noexcept {
|
|
|
|
while (!text.empty() && !range.Empty() && (text.front() == CharAt(range.start))) {
|
|
|
|
text.remove_prefix(1);
|
|
|
|
range.start++;
|
|
|
|
}
|
|
|
|
while (!text.empty() && !range.Empty() && (text.back() == CharAt(range.end-1))) {
|
|
|
|
text.remove_suffix(1);
|
|
|
|
range.end--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-24 23:35:41 +00:00
|
|
|
// Document only modified by gateways DeleteChars, InsertString, Undo, Redo, and SetStyleAt.
|
|
|
|
// SetStyleAt does not change the persistent state of a document
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
bool Document::DeleteChars(Sci::Position pos, Sci::Position len) {
|
2015-06-07 21:19:26 +00:00
|
|
|
if (pos < 0)
|
|
|
|
return false;
|
2013-08-28 00:44:27 +00:00
|
|
|
if (len <= 0)
|
2009-04-24 23:35:41 +00:00
|
|
|
return false;
|
2019-07-21 13:26:02 +00:00
|
|
|
if ((pos + len) > LengthNoExcept())
|
2009-04-24 23:35:41 +00:00
|
|
|
return false;
|
|
|
|
CheckReadOnly();
|
|
|
|
if (enteredModification != 0) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
enteredModification++;
|
|
|
|
if (!cb.IsReadOnly()) {
|
|
|
|
NotifyModified(
|
|
|
|
DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::BeforeDelete | ModificationFlags::User,
|
2009-04-24 23:35:41 +00:00
|
|
|
pos, len,
|
2022-01-04 23:07:50 +00:00
|
|
|
0, nullptr));
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line prevLinesTotal = LinesTotal();
|
|
|
|
const bool startSavePoint = cb.IsSavePoint();
|
2009-04-24 23:35:41 +00:00
|
|
|
bool startSequence = false;
|
|
|
|
const char *text = cb.DeleteChars(pos, len, startSequence);
|
|
|
|
if (startSavePoint && cb.IsCollectingUndo())
|
2021-02-21 04:53:09 +00:00
|
|
|
NotifySavePoint(false);
|
2019-07-21 13:26:02 +00:00
|
|
|
if ((pos < LengthNoExcept()) || (pos == 0))
|
2009-04-24 23:35:41 +00:00
|
|
|
ModifiedAt(pos);
|
|
|
|
else
|
|
|
|
ModifiedAt(pos-1);
|
|
|
|
NotifyModified(
|
|
|
|
DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::DeleteText | ModificationFlags::User |
|
|
|
|
(startSequence?ModificationFlags::StartAction:ModificationFlags::None),
|
2009-04-24 23:35:41 +00:00
|
|
|
pos, len,
|
|
|
|
LinesTotal() - prevLinesTotal, text));
|
|
|
|
}
|
|
|
|
enteredModification--;
|
|
|
|
}
|
|
|
|
return !cb.IsReadOnly();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Insert a string with a length.
|
|
|
|
*/
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::InsertString(Sci::Position position, const char *s, Sci::Position insertLength) {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (insertLength <= 0) {
|
2015-06-07 21:19:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
CheckReadOnly(); // Application may change read only state here
|
|
|
|
if (cb.IsReadOnly()) {
|
|
|
|
return 0;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
if (enteredModification != 0) {
|
2015-06-07 21:19:26 +00:00
|
|
|
return 0;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
2015-06-07 21:19:26 +00:00
|
|
|
enteredModification++;
|
|
|
|
insertionSet = false;
|
|
|
|
insertion.clear();
|
|
|
|
NotifyModified(
|
|
|
|
DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::InsertCheck,
|
2015-06-07 21:19:26 +00:00
|
|
|
position, insertLength,
|
|
|
|
0, s));
|
|
|
|
if (insertionSet) {
|
|
|
|
s = insertion.c_str();
|
2019-05-04 18:14:48 +00:00
|
|
|
insertLength = insertion.length();
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
|
|
|
NotifyModified(
|
|
|
|
DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::BeforeInsert | ModificationFlags::User,
|
2015-06-07 21:19:26 +00:00
|
|
|
position, insertLength,
|
|
|
|
0, s));
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line prevLinesTotal = LinesTotal();
|
|
|
|
const bool startSavePoint = cb.IsSavePoint();
|
2015-06-07 21:19:26 +00:00
|
|
|
bool startSequence = false;
|
|
|
|
const char *text = cb.InsertString(position, s, insertLength, startSequence);
|
|
|
|
if (startSavePoint && cb.IsCollectingUndo())
|
2021-02-21 04:53:09 +00:00
|
|
|
NotifySavePoint(false);
|
2015-06-07 21:19:26 +00:00
|
|
|
ModifiedAt(position);
|
|
|
|
NotifyModified(
|
|
|
|
DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::InsertText | ModificationFlags::User |
|
|
|
|
(startSequence?ModificationFlags::StartAction:ModificationFlags::None),
|
2015-06-07 21:19:26 +00:00
|
|
|
position, insertLength,
|
|
|
|
LinesTotal() - prevLinesTotal, text));
|
|
|
|
if (insertionSet) { // Free memory as could be large
|
|
|
|
std::string().swap(insertion);
|
|
|
|
}
|
|
|
|
enteredModification--;
|
|
|
|
return insertLength;
|
|
|
|
}
|
|
|
|
|
2022-12-10 12:35:16 +00:00
|
|
|
Sci::Position Document::InsertString(Sci::Position position, std::string_view sv) {
|
|
|
|
return InsertString(position, sv.data(), sv.length());
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::ChangeInsertion(const char *s, Sci::Position length) {
|
2015-06-07 21:19:26 +00:00
|
|
|
insertionSet = true;
|
|
|
|
insertion.assign(s, length);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
int SCI_METHOD Document::AddData(const char *data, Sci_Position length) {
|
2013-08-28 00:44:27 +00:00
|
|
|
try {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position position = Length();
|
2015-06-07 21:19:26 +00:00
|
|
|
InsertString(position, data, length);
|
2013-08-28 00:44:27 +00:00
|
|
|
} catch (std::bad_alloc &) {
|
2022-01-04 23:07:50 +00:00
|
|
|
return static_cast<int>(Status::BadAlloc);
|
2013-08-28 00:44:27 +00:00
|
|
|
} catch (...) {
|
2022-01-04 23:07:50 +00:00
|
|
|
return static_cast<int>(Status::Failure);
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
return static_cast<int>(Status::Ok);
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
IDocumentEditable *Document::AsDocumentEditable() noexcept {
|
|
|
|
return static_cast<IDocumentEditable *>(this);
|
|
|
|
}
|
|
|
|
|
Update to scintilla 5.4.3 (from 5.4.1) & Lexilla 5.3.1
Sintilla [Release 5.4.3](https://www.scintilla.org/scintilla543.zip)
* Release 5.4.3: Released 9 March 2024
1. Fix redo failure introduced with 5.4.2. [Bug #2432](https://sourceforge.net/p/scintilla/bugs/2432/).
2. Add SC_AUTOCOMPLETE_SELECT_FIRST_ITEM option to always selects the first item in the autocompletion list. [Bug #2403](https://sourceforge.net/p/scintilla/bugs/2403/).
* Release 5.4.2: Released 5 March 2024
1. Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
2. Add APIs for saving and restoring undo history.
3. For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
4. For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
5. For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
6. For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
Lexilla [Release 5.3.1](https://www.scintilla.org/lexilla531.zip)
* Release 5.3.1: Released 5 March 2024
1. Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
2. Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
3. Batch: Fix handling ':' next to keywords. Issue #222.
4. JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
5. Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
6. Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
Close #14834
2024-03-10 22:19:01 +00:00
|
|
|
void *SCI_METHOD Document::ConvertToDocument() {
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
return AsDocumentEditable();
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::Undo() {
|
|
|
|
Sci::Position newPos = -1;
|
2009-04-24 23:35:41 +00:00
|
|
|
CheckReadOnly();
|
2013-08-28 00:44:27 +00:00
|
|
|
if ((enteredModification == 0) && (cb.IsCollectingUndo())) {
|
2009-04-24 23:35:41 +00:00
|
|
|
enteredModification++;
|
|
|
|
if (!cb.IsReadOnly()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const bool startSavePoint = cb.IsSavePoint();
|
2009-04-24 23:35:41 +00:00
|
|
|
bool multiLine = false;
|
2019-05-04 18:14:48 +00:00
|
|
|
const int steps = cb.StartUndo();
|
2009-04-24 23:35:41 +00:00
|
|
|
//Platform::DebugPrintf("Steps=%d\n", steps);
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
Range coalescedRemove; // Default is empty at 0
|
2009-04-24 23:35:41 +00:00
|
|
|
for (int step = 0; step < steps; step++) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line prevLinesTotal = LinesTotal();
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
const Action action = cb.GetUndoStep();
|
2022-01-04 23:07:50 +00:00
|
|
|
if (action.at == ActionType::remove) {
|
2009-04-24 23:35:41 +00:00
|
|
|
NotifyModified(DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::BeforeInsert | ModificationFlags::Undo, action));
|
|
|
|
} else if (action.at == ActionType::container) {
|
|
|
|
DocModification dm(ModificationFlags::Container | ModificationFlags::Undo);
|
2009-06-24 19:09:31 +00:00
|
|
|
dm.token = action.position;
|
|
|
|
NotifyModified(dm);
|
2009-04-24 23:35:41 +00:00
|
|
|
} else {
|
|
|
|
NotifyModified(DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::BeforeDelete | ModificationFlags::Undo, action));
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
cb.PerformUndoStep();
|
2022-01-04 23:07:50 +00:00
|
|
|
if (action.at != ActionType::container) {
|
2013-08-28 00:44:27 +00:00
|
|
|
ModifiedAt(action.position);
|
|
|
|
newPos = action.position;
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags modFlags = ModificationFlags::Undo;
|
2009-04-24 23:35:41 +00:00
|
|
|
// With undo, an insertion action becomes a deletion notification
|
2022-01-04 23:07:50 +00:00
|
|
|
if (action.at == ActionType::remove) {
|
2009-04-24 23:35:41 +00:00
|
|
|
newPos += action.lenData;
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::InsertText;
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
if (coalescedRemove.Contains(action.position)) {
|
|
|
|
coalescedRemove.end += action.lenData;
|
|
|
|
newPos = coalescedRemove.end;
|
2013-08-28 00:44:27 +00:00
|
|
|
} else {
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
coalescedRemove = Range(action.position, action.position + action.lenData);
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (action.at == ActionType::insert) {
|
|
|
|
modFlags |= ModificationFlags::DeleteText;
|
Update to scintilla 5.4.3 (from 5.4.1) & Lexilla 5.3.1
Sintilla [Release 5.4.3](https://www.scintilla.org/scintilla543.zip)
* Release 5.4.3: Released 9 March 2024
1. Fix redo failure introduced with 5.4.2. [Bug #2432](https://sourceforge.net/p/scintilla/bugs/2432/).
2. Add SC_AUTOCOMPLETE_SELECT_FIRST_ITEM option to always selects the first item in the autocompletion list. [Bug #2403](https://sourceforge.net/p/scintilla/bugs/2403/).
* Release 5.4.2: Released 5 March 2024
1. Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
2. Add APIs for saving and restoring undo history.
3. For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
4. For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
5. For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
6. For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
Lexilla [Release 5.3.1](https://www.scintilla.org/lexilla531.zip)
* Release 5.3.1: Released 5 March 2024
1. Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
2. Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
3. Batch: Fix handling ':' next to keywords. Issue #222.
4. JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
5. Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
6. Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
Close #14834
2024-03-10 22:19:01 +00:00
|
|
|
coalescedRemove = Range();
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
if (steps > 1)
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::MultiStepUndoRedo;
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line linesAdded = LinesTotal() - prevLinesTotal;
|
2009-04-24 23:35:41 +00:00
|
|
|
if (linesAdded != 0)
|
|
|
|
multiLine = true;
|
|
|
|
if (step == steps - 1) {
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::LastStepInUndoRedo;
|
2009-04-24 23:35:41 +00:00
|
|
|
if (multiLine)
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::MultilineUndoRedo;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
NotifyModified(DocModification(modFlags, action.position, action.lenData,
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
linesAdded, action.data));
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
const bool endSavePoint = cb.IsSavePoint();
|
2009-04-24 23:35:41 +00:00
|
|
|
if (startSavePoint != endSavePoint)
|
|
|
|
NotifySavePoint(endSavePoint);
|
|
|
|
}
|
|
|
|
enteredModification--;
|
|
|
|
}
|
|
|
|
return newPos;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::Redo() {
|
|
|
|
Sci::Position newPos = -1;
|
2009-04-24 23:35:41 +00:00
|
|
|
CheckReadOnly();
|
2013-08-28 00:44:27 +00:00
|
|
|
if ((enteredModification == 0) && (cb.IsCollectingUndo())) {
|
2009-04-24 23:35:41 +00:00
|
|
|
enteredModification++;
|
|
|
|
if (!cb.IsReadOnly()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const bool startSavePoint = cb.IsSavePoint();
|
2009-04-24 23:35:41 +00:00
|
|
|
bool multiLine = false;
|
2019-05-04 18:14:48 +00:00
|
|
|
const int steps = cb.StartRedo();
|
2009-04-24 23:35:41 +00:00
|
|
|
for (int step = 0; step < steps; step++) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line prevLinesTotal = LinesTotal();
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
const Action action = cb.GetRedoStep();
|
2022-01-04 23:07:50 +00:00
|
|
|
if (action.at == ActionType::insert) {
|
2009-04-24 23:35:41 +00:00
|
|
|
NotifyModified(DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::BeforeInsert | ModificationFlags::Redo, action));
|
|
|
|
} else if (action.at == ActionType::container) {
|
|
|
|
DocModification dm(ModificationFlags::Container | ModificationFlags::Redo);
|
2009-06-24 19:09:31 +00:00
|
|
|
dm.token = action.position;
|
|
|
|
NotifyModified(dm);
|
2009-04-24 23:35:41 +00:00
|
|
|
} else {
|
|
|
|
NotifyModified(DocModification(
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags::BeforeDelete | ModificationFlags::Redo, action));
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
cb.PerformRedoStep();
|
2022-01-04 23:07:50 +00:00
|
|
|
if (action.at != ActionType::container) {
|
2009-06-24 19:09:31 +00:00
|
|
|
ModifiedAt(action.position);
|
|
|
|
newPos = action.position;
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
ModificationFlags modFlags = ModificationFlags::Redo;
|
|
|
|
if (action.at == ActionType::insert) {
|
2009-04-24 23:35:41 +00:00
|
|
|
newPos += action.lenData;
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::InsertText;
|
|
|
|
} else if (action.at == ActionType::remove) {
|
|
|
|
modFlags |= ModificationFlags::DeleteText;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
if (steps > 1)
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::MultiStepUndoRedo;
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line linesAdded = LinesTotal() - prevLinesTotal;
|
2009-04-24 23:35:41 +00:00
|
|
|
if (linesAdded != 0)
|
|
|
|
multiLine = true;
|
|
|
|
if (step == steps - 1) {
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::LastStepInUndoRedo;
|
2009-04-24 23:35:41 +00:00
|
|
|
if (multiLine)
|
2022-01-04 23:07:50 +00:00
|
|
|
modFlags |= ModificationFlags::MultilineUndoRedo;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
NotifyModified(
|
|
|
|
DocModification(modFlags, action.position, action.lenData,
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
linesAdded, action.data));
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
const bool endSavePoint = cb.IsSavePoint();
|
2009-04-24 23:35:41 +00:00
|
|
|
if (startSavePoint != endSavePoint)
|
|
|
|
NotifySavePoint(endSavePoint);
|
|
|
|
}
|
|
|
|
enteredModification--;
|
|
|
|
}
|
|
|
|
return newPos;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::DelChar(Sci::Position pos) {
|
2009-04-24 23:35:41 +00:00
|
|
|
DeleteChars(pos, LenChar(pos));
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::DelCharBack(Sci::Position pos) {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (pos <= 0) {
|
|
|
|
return;
|
|
|
|
} else if (IsCrLf(pos - 2)) {
|
|
|
|
DeleteChars(pos - 2, 2);
|
|
|
|
} else if (dbcsCodePage) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position startChar = NextPosition(pos, -1);
|
2009-04-24 23:35:41 +00:00
|
|
|
DeleteChars(startChar, pos - startChar);
|
|
|
|
} else {
|
|
|
|
DeleteChars(pos - 1, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
static constexpr Sci::Position NextTab(Sci::Position pos, Sci::Position tabSize) noexcept {
|
2009-04-24 23:35:41 +00:00
|
|
|
return ((pos / tabSize) + 1) * tabSize;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
static std::string CreateIndentation(Sci::Position indent, int tabSize, bool insertSpaces) {
|
2013-08-28 00:44:27 +00:00
|
|
|
std::string indentation;
|
2009-04-24 23:35:41 +00:00
|
|
|
if (!insertSpaces) {
|
2013-08-28 00:44:27 +00:00
|
|
|
while (indent >= tabSize) {
|
|
|
|
indentation += '\t';
|
2009-04-24 23:35:41 +00:00
|
|
|
indent -= tabSize;
|
|
|
|
}
|
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
while (indent > 0) {
|
|
|
|
indentation += ' ';
|
2009-04-24 23:35:41 +00:00
|
|
|
indent--;
|
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
return indentation;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
int SCI_METHOD Document::GetLineIndentation(Sci_Position line) {
|
2009-04-24 23:35:41 +00:00
|
|
|
int indent = 0;
|
|
|
|
if ((line >= 0) && (line < LinesTotal())) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position lineStart = LineStart(line);
|
|
|
|
const Sci::Position length = Length();
|
|
|
|
for (Sci::Position i = lineStart; i < length; i++) {
|
|
|
|
const char ch = cb.CharAt(i);
|
2009-04-24 23:35:41 +00:00
|
|
|
if (ch == ' ')
|
|
|
|
indent++;
|
|
|
|
else if (ch == '\t')
|
2019-05-04 18:14:48 +00:00
|
|
|
indent = static_cast<int>(NextTab(indent, tabInChars));
|
2009-04-24 23:35:41 +00:00
|
|
|
else
|
|
|
|
return indent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return indent;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::SetLineIndentation(Sci::Line line, Sci::Position indent) {
|
|
|
|
const int indentOfLine = GetLineIndentation(line);
|
2009-04-24 23:35:41 +00:00
|
|
|
if (indent < 0)
|
|
|
|
indent = 0;
|
|
|
|
if (indent != indentOfLine) {
|
2023-02-09 16:57:24 +00:00
|
|
|
const std::string linebuf = CreateIndentation(indent, tabInChars, !useTabs);
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position thisLineStart = LineStart(line);
|
|
|
|
const Sci::Position indentPos = GetLineIndentPosition(line);
|
2009-08-23 02:24:48 +00:00
|
|
|
UndoGroup ug(this);
|
2009-04-24 23:35:41 +00:00
|
|
|
DeleteChars(thisLineStart, indentPos - thisLineStart);
|
2023-02-09 16:57:24 +00:00
|
|
|
return thisLineStart + InsertString(thisLineStart, linebuf);
|
2015-06-07 21:19:26 +00:00
|
|
|
} else {
|
|
|
|
return GetLineIndentPosition(line);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::GetLineIndentPosition(Sci::Line line) const {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (line < 0)
|
|
|
|
return 0;
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position pos = LineStart(line);
|
|
|
|
const Sci::Position length = Length();
|
2013-08-28 00:44:27 +00:00
|
|
|
while ((pos < length) && IsSpaceOrTab(cb.CharAt(pos))) {
|
2009-04-24 23:35:41 +00:00
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2022-12-10 12:35:16 +00:00
|
|
|
Sci::Position Document::GetColumn(Sci::Position pos) const {
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position column = 0;
|
|
|
|
const Sci::Line line = SciLineFromPosition(pos);
|
2009-04-24 23:35:41 +00:00
|
|
|
if ((line >= 0) && (line < LinesTotal())) {
|
2019-05-04 18:14:48 +00:00
|
|
|
for (Sci::Position i = LineStart(line); i < pos;) {
|
|
|
|
const char ch = cb.CharAt(i);
|
2009-04-24 23:35:41 +00:00
|
|
|
if (ch == '\t') {
|
|
|
|
column = NextTab(column, tabInChars);
|
|
|
|
i++;
|
|
|
|
} else if (ch == '\r') {
|
|
|
|
return column;
|
|
|
|
} else if (ch == '\n') {
|
|
|
|
return column;
|
|
|
|
} else if (i >= Length()) {
|
|
|
|
return column;
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (UTF8IsAscii(ch)) {
|
|
|
|
column++;
|
|
|
|
i++;
|
2009-04-24 23:35:41 +00:00
|
|
|
} else {
|
|
|
|
column++;
|
2010-09-05 22:56:27 +00:00
|
|
|
i = NextPosition(i, 1);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return column;
|
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
Sci::Position Document::CountCharacters(Sci::Position startPos, Sci::Position endPos) const noexcept {
|
2013-08-28 00:44:27 +00:00
|
|
|
startPos = MovePositionOutsideChar(startPos, 1, false);
|
|
|
|
endPos = MovePositionOutsideChar(endPos, -1, false);
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position count = 0;
|
|
|
|
Sci::Position i = startPos;
|
2013-08-28 00:44:27 +00:00
|
|
|
while (i < endPos) {
|
|
|
|
count++;
|
|
|
|
i = NextPosition(i, 1);
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
Sci::Position Document::CountUTF16(Sci::Position startPos, Sci::Position endPos) const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
startPos = MovePositionOutsideChar(startPos, 1, false);
|
|
|
|
endPos = MovePositionOutsideChar(endPos, -1, false);
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position count = 0;
|
|
|
|
Sci::Position i = startPos;
|
2015-06-07 21:19:26 +00:00
|
|
|
while (i < endPos) {
|
|
|
|
count++;
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position next = NextPosition(i, 1);
|
2015-06-07 21:19:26 +00:00
|
|
|
if ((next - i) > 3)
|
|
|
|
count++;
|
|
|
|
i = next;
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::FindColumn(Sci::Line line, Sci::Position column) {
|
|
|
|
Sci::Position position = LineStart(line);
|
2009-04-24 23:35:41 +00:00
|
|
|
if ((line >= 0) && (line < LinesTotal())) {
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position columnCurrent = 0;
|
2009-04-24 23:35:41 +00:00
|
|
|
while ((columnCurrent < column) && (position < Length())) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const char ch = cb.CharAt(position);
|
2009-04-24 23:35:41 +00:00
|
|
|
if (ch == '\t') {
|
|
|
|
columnCurrent = NextTab(columnCurrent, tabInChars);
|
2013-08-28 00:44:27 +00:00
|
|
|
if (columnCurrent > column)
|
|
|
|
return position;
|
2009-04-24 23:35:41 +00:00
|
|
|
position++;
|
|
|
|
} else if (ch == '\r') {
|
|
|
|
return position;
|
|
|
|
} else if (ch == '\n') {
|
|
|
|
return position;
|
|
|
|
} else {
|
|
|
|
columnCurrent++;
|
2010-09-05 22:56:27 +00:00
|
|
|
position = NextPosition(position, 1);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::Indent(bool forwards, Sci::Line lineBottom, Sci::Line lineTop) {
|
2009-04-24 23:35:41 +00:00
|
|
|
// Dedent - suck white space off the front of the line to dedent by equivalent of a tab
|
2019-05-04 18:14:48 +00:00
|
|
|
for (Sci::Line line = lineBottom; line >= lineTop; line--) {
|
|
|
|
const Sci::Position indentOfLine = GetLineIndentation(line);
|
2009-04-24 23:35:41 +00:00
|
|
|
if (forwards) {
|
|
|
|
if (LineStart(line) < LineEnd(line)) {
|
|
|
|
SetLineIndentation(line, indentOfLine + IndentSize());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
SetLineIndentation(line, indentOfLine - IndentSize());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert line endings for a piece of text to a particular mode.
|
|
|
|
// Stop at len or when a NUL is found.
|
2022-01-04 23:07:50 +00:00
|
|
|
std::string Document::TransformLineEnds(const char *s, size_t len, EndOfLine eolModeWanted) {
|
2013-08-28 00:44:27 +00:00
|
|
|
std::string dest;
|
|
|
|
for (size_t i = 0; (i < len) && (s[i]); i++) {
|
|
|
|
if (s[i] == '\n' || s[i] == '\r') {
|
2022-01-04 23:07:50 +00:00
|
|
|
if (eolModeWanted == EndOfLine::Cr) {
|
2013-08-28 00:44:27 +00:00
|
|
|
dest.push_back('\r');
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (eolModeWanted == EndOfLine::Lf) {
|
2013-08-28 00:44:27 +00:00
|
|
|
dest.push_back('\n');
|
2022-01-04 23:07:50 +00:00
|
|
|
} else { // eolModeWanted == EndOfLine::CrLf
|
2013-08-28 00:44:27 +00:00
|
|
|
dest.push_back('\r');
|
|
|
|
dest.push_back('\n');
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
if ((s[i] == '\r') && (i+1 < len) && (s[i+1] == '\n')) {
|
2009-04-24 23:35:41 +00:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
} else {
|
2013-08-28 00:44:27 +00:00
|
|
|
dest.push_back(s[i]);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
void Document::ConvertLineEnds(EndOfLine eolModeSet) {
|
2009-08-23 02:24:48 +00:00
|
|
|
UndoGroup ug(this);
|
2009-04-24 23:35:41 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
for (Sci::Position pos = 0; pos < Length(); pos++) {
|
2023-02-09 16:57:24 +00:00
|
|
|
const char ch = cb.CharAt(pos);
|
|
|
|
if (ch == '\r') {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (cb.CharAt(pos + 1) == '\n') {
|
|
|
|
// CRLF
|
2022-01-04 23:07:50 +00:00
|
|
|
if (eolModeSet == EndOfLine::Cr) {
|
2009-04-24 23:35:41 +00:00
|
|
|
DeleteChars(pos + 1, 1); // Delete the LF
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (eolModeSet == EndOfLine::Lf) {
|
2009-04-24 23:35:41 +00:00
|
|
|
DeleteChars(pos, 1); // Delete the CR
|
|
|
|
} else {
|
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// CR
|
2022-01-04 23:07:50 +00:00
|
|
|
if (eolModeSet == EndOfLine::CrLf) {
|
2015-06-07 21:19:26 +00:00
|
|
|
pos += InsertString(pos + 1, "\n", 1); // Insert LF
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (eolModeSet == EndOfLine::Lf) {
|
2015-06-07 21:19:26 +00:00
|
|
|
pos += InsertString(pos, "\n", 1); // Insert LF
|
|
|
|
DeleteChars(pos, 1); // Delete CR
|
|
|
|
pos--;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
2023-02-09 16:57:24 +00:00
|
|
|
} else if (ch == '\n') {
|
2009-04-24 23:35:41 +00:00
|
|
|
// LF
|
2022-01-04 23:07:50 +00:00
|
|
|
if (eolModeSet == EndOfLine::CrLf) {
|
2015-06-07 21:19:26 +00:00
|
|
|
pos += InsertString(pos, "\r", 1); // Insert CR
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (eolModeSet == EndOfLine::Cr) {
|
2015-06-07 21:19:26 +00:00
|
|
|
pos += InsertString(pos, "\r", 1); // Insert CR
|
|
|
|
DeleteChars(pos, 1); // Delete LF
|
|
|
|
pos--;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-02-09 16:57:24 +00:00
|
|
|
std::string_view Document::EOLString() const noexcept {
|
|
|
|
if (eolMode == EndOfLine::CrLf) {
|
|
|
|
return "\r\n";
|
|
|
|
} else if (eolMode == EndOfLine::Cr) {
|
|
|
|
return "\r";
|
|
|
|
} else {
|
|
|
|
return "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
DocumentOption Document::Options() const noexcept {
|
|
|
|
return (IsLarge() ? DocumentOption::TextLarge : DocumentOption::Default) |
|
|
|
|
(cb.HasStyles() ? DocumentOption::Default : DocumentOption::StylesNone);
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Document::IsWhiteLine(Sci::Line line) const {
|
|
|
|
Sci::Position currentChar = LineStart(line);
|
|
|
|
const Sci::Position endLine = LineEnd(line);
|
2009-04-24 23:35:41 +00:00
|
|
|
while (currentChar < endLine) {
|
2019-05-04 18:14:48 +00:00
|
|
|
if (!IsSpaceOrTab(cb.CharAt(currentChar))) {
|
2009-04-24 23:35:41 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
++currentChar;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::ParaUp(Sci::Position pos) const {
|
|
|
|
Sci::Line line = SciLineFromPosition(pos);
|
2022-12-10 12:35:16 +00:00
|
|
|
const Sci::Position start = LineStart(line);
|
|
|
|
if (pos == start) {
|
|
|
|
line--;
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
while (line >= 0 && IsWhiteLine(line)) { // skip empty lines
|
|
|
|
line--;
|
|
|
|
}
|
|
|
|
while (line >= 0 && !IsWhiteLine(line)) { // skip non-empty lines
|
|
|
|
line--;
|
|
|
|
}
|
|
|
|
line++;
|
|
|
|
return LineStart(line);
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::ParaDown(Sci::Position pos) const {
|
|
|
|
Sci::Line line = SciLineFromPosition(pos);
|
2009-04-24 23:35:41 +00:00
|
|
|
while (line < LinesTotal() && !IsWhiteLine(line)) { // skip non-empty lines
|
|
|
|
line++;
|
|
|
|
}
|
|
|
|
while (line < LinesTotal() && IsWhiteLine(line)) { // skip empty lines
|
|
|
|
line++;
|
|
|
|
}
|
|
|
|
if (line < LinesTotal())
|
|
|
|
return LineStart(line);
|
|
|
|
else // end of a document
|
|
|
|
return LineEnd(line-1);
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
CharacterClass Document::WordCharacterClass(unsigned int ch) const {
|
|
|
|
if (dbcsCodePage && (ch >= 0x80)) {
|
|
|
|
if (CpUtf8 == dbcsCodePage) {
|
2019-05-04 18:14:48 +00:00
|
|
|
// Use hard coded Unicode class
|
2019-07-21 13:26:02 +00:00
|
|
|
const CharacterCategory cc = charMap.CategoryFor(ch);
|
2019-05-04 18:14:48 +00:00
|
|
|
switch (cc) {
|
|
|
|
|
|
|
|
// Separator, Line/Paragraph
|
|
|
|
case ccZl:
|
|
|
|
case ccZp:
|
2022-01-04 23:07:50 +00:00
|
|
|
return CharacterClass::newLine;
|
2019-05-04 18:14:48 +00:00
|
|
|
|
|
|
|
// Separator, Space
|
|
|
|
case ccZs:
|
|
|
|
// Other
|
|
|
|
case ccCc:
|
|
|
|
case ccCf:
|
|
|
|
case ccCs:
|
|
|
|
case ccCo:
|
|
|
|
case ccCn:
|
2022-01-04 23:07:50 +00:00
|
|
|
return CharacterClass::space;
|
2019-05-04 18:14:48 +00:00
|
|
|
|
|
|
|
// Letter
|
|
|
|
case ccLu:
|
|
|
|
case ccLl:
|
|
|
|
case ccLt:
|
|
|
|
case ccLm:
|
|
|
|
case ccLo:
|
|
|
|
// Number
|
|
|
|
case ccNd:
|
|
|
|
case ccNl:
|
|
|
|
case ccNo:
|
|
|
|
// Mark - includes combining diacritics
|
|
|
|
case ccMn:
|
|
|
|
case ccMc:
|
|
|
|
case ccMe:
|
2022-01-04 23:07:50 +00:00
|
|
|
return CharacterClass::word;
|
2019-05-04 18:14:48 +00:00
|
|
|
|
|
|
|
// Punctuation
|
|
|
|
case ccPc:
|
|
|
|
case ccPd:
|
|
|
|
case ccPs:
|
|
|
|
case ccPe:
|
|
|
|
case ccPi:
|
|
|
|
case ccPf:
|
|
|
|
case ccPo:
|
|
|
|
// Symbol
|
|
|
|
case ccSm:
|
|
|
|
case ccSc:
|
|
|
|
case ccSk:
|
|
|
|
case ccSo:
|
2022-01-04 23:07:50 +00:00
|
|
|
return CharacterClass::punctuation;
|
2019-05-04 18:14:48 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Asian DBCS
|
2022-01-04 23:07:50 +00:00
|
|
|
return CharacterClass::word;
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return charClass.GetClass(static_cast<unsigned char>(ch));
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-02-21 04:53:09 +00:00
|
|
|
* Used by commands that want to select whole words.
|
2009-04-24 23:35:41 +00:00
|
|
|
* Finds the start of word at pos when delta < 0 or the end of the word when delta >= 0.
|
|
|
|
*/
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::ExtendWordSelect(Sci::Position pos, int delta, bool onlyWordCharacters) const {
|
2022-01-04 23:07:50 +00:00
|
|
|
CharacterClass ccStart = CharacterClass::word;
|
2009-04-24 23:35:41 +00:00
|
|
|
if (delta < 0) {
|
2019-05-04 18:14:48 +00:00
|
|
|
if (!onlyWordCharacters) {
|
|
|
|
const CharacterExtracted ce = CharacterBefore(pos);
|
|
|
|
ccStart = WordCharacterClass(ce.character);
|
|
|
|
}
|
|
|
|
while (pos > 0) {
|
|
|
|
const CharacterExtracted ce = CharacterBefore(pos);
|
|
|
|
if (WordCharacterClass(ce.character) != ccStart)
|
|
|
|
break;
|
|
|
|
pos -= ce.widthBytes;
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
} else {
|
2019-07-21 13:26:02 +00:00
|
|
|
if (!onlyWordCharacters && pos < LengthNoExcept()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const CharacterExtracted ce = CharacterAfter(pos);
|
|
|
|
ccStart = WordCharacterClass(ce.character);
|
|
|
|
}
|
2019-07-21 13:26:02 +00:00
|
|
|
while (pos < LengthNoExcept()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const CharacterExtracted ce = CharacterAfter(pos);
|
|
|
|
if (WordCharacterClass(ce.character) != ccStart)
|
|
|
|
break;
|
|
|
|
pos += ce.widthBytes;
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
2010-07-12 22:19:51 +00:00
|
|
|
return MovePositionOutsideChar(pos, delta, true);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find the start of the next word in either a forward (delta >= 0) or backwards direction
|
|
|
|
* (delta < 0).
|
|
|
|
* This is looking for a transition between character classes although there is also some
|
|
|
|
* additional movement to transit white space.
|
|
|
|
* Used by cursor movement by word commands.
|
|
|
|
*/
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::NextWordStart(Sci::Position pos, int delta) const {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (delta < 0) {
|
2019-05-04 18:14:48 +00:00
|
|
|
while (pos > 0) {
|
|
|
|
const CharacterExtracted ce = CharacterBefore(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
if (WordCharacterClass(ce.character) != CharacterClass::space)
|
2019-05-04 18:14:48 +00:00
|
|
|
break;
|
|
|
|
pos -= ce.widthBytes;
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
if (pos > 0) {
|
2019-05-04 18:14:48 +00:00
|
|
|
CharacterExtracted ce = CharacterBefore(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
const CharacterClass ccStart = WordCharacterClass(ce.character);
|
2019-05-04 18:14:48 +00:00
|
|
|
while (pos > 0) {
|
|
|
|
ce = CharacterBefore(pos);
|
|
|
|
if (WordCharacterClass(ce.character) != ccStart)
|
|
|
|
break;
|
|
|
|
pos -= ce.widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2019-05-04 18:14:48 +00:00
|
|
|
CharacterExtracted ce = CharacterAfter(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
const CharacterClass ccStart = WordCharacterClass(ce.character);
|
2019-07-21 13:26:02 +00:00
|
|
|
while (pos < LengthNoExcept()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
ce = CharacterAfter(pos);
|
|
|
|
if (WordCharacterClass(ce.character) != ccStart)
|
|
|
|
break;
|
|
|
|
pos += ce.widthBytes;
|
|
|
|
}
|
2019-07-21 13:26:02 +00:00
|
|
|
while (pos < LengthNoExcept()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
ce = CharacterAfter(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
if (WordCharacterClass(ce.character) != CharacterClass::space)
|
2019-05-04 18:14:48 +00:00
|
|
|
break;
|
|
|
|
pos += ce.widthBytes;
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find the end of the next word in either a forward (delta >= 0) or backwards direction
|
|
|
|
* (delta < 0).
|
|
|
|
* This is looking for a transition between character classes although there is also some
|
|
|
|
* additional movement to transit white space.
|
|
|
|
* Used by cursor movement by word commands.
|
|
|
|
*/
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::NextWordEnd(Sci::Position pos, int delta) const {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (delta < 0) {
|
|
|
|
if (pos > 0) {
|
2019-05-04 18:14:48 +00:00
|
|
|
CharacterExtracted ce = CharacterBefore(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
const CharacterClass ccStart = WordCharacterClass(ce.character);
|
|
|
|
if (ccStart != CharacterClass::space) {
|
2019-05-04 18:14:48 +00:00
|
|
|
while (pos > 0) {
|
|
|
|
ce = CharacterBefore(pos);
|
|
|
|
if (WordCharacterClass(ce.character) != ccStart)
|
|
|
|
break;
|
|
|
|
pos -= ce.widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
while (pos > 0) {
|
|
|
|
ce = CharacterBefore(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
if (WordCharacterClass(ce.character) != CharacterClass::space)
|
2019-05-04 18:14:48 +00:00
|
|
|
break;
|
|
|
|
pos -= ce.widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2019-07-21 13:26:02 +00:00
|
|
|
while (pos < LengthNoExcept()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const CharacterExtracted ce = CharacterAfter(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
if (WordCharacterClass(ce.character) != CharacterClass::space)
|
2019-05-04 18:14:48 +00:00
|
|
|
break;
|
|
|
|
pos += ce.widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
2019-07-21 13:26:02 +00:00
|
|
|
if (pos < LengthNoExcept()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
CharacterExtracted ce = CharacterAfter(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
const CharacterClass ccStart = WordCharacterClass(ce.character);
|
2019-07-21 13:26:02 +00:00
|
|
|
while (pos < LengthNoExcept()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
ce = CharacterAfter(pos);
|
|
|
|
if (WordCharacterClass(ce.character) != ccStart)
|
|
|
|
break;
|
|
|
|
pos += ce.widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
constexpr bool IsWordEdge(CharacterClass cc, CharacterClass ccNext) noexcept {
|
|
|
|
return (cc != ccNext) &&
|
|
|
|
(cc == CharacterClass::word || cc == CharacterClass::punctuation);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-04-24 23:35:41 +00:00
|
|
|
/**
|
|
|
|
* Check that the character at the given position is a word or punctuation character and that
|
|
|
|
* the previous character is of a different character class.
|
|
|
|
*/
|
2019-05-04 18:14:48 +00:00
|
|
|
bool Document::IsWordStartAt(Sci::Position pos) const {
|
2019-07-21 13:26:02 +00:00
|
|
|
if (pos >= LengthNoExcept())
|
2019-05-04 18:14:48 +00:00
|
|
|
return false;
|
2022-01-04 23:07:50 +00:00
|
|
|
if (pos >= 0) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const CharacterExtracted cePos = CharacterAfter(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
// At start of document, treat as if space before so can be word start
|
|
|
|
const CharacterExtracted cePrev = (pos > 0) ?
|
|
|
|
CharacterBefore(pos) : CharacterExtracted(' ', 1);
|
|
|
|
return IsWordEdge(WordCharacterClass(cePos.character), WordCharacterClass(cePrev.character));
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-01-04 23:07:50 +00:00
|
|
|
* Check that the character before the given position is a word or punctuation character and that
|
2009-04-24 23:35:41 +00:00
|
|
|
* the next character is of a different character class.
|
|
|
|
*/
|
2019-05-04 18:14:48 +00:00
|
|
|
bool Document::IsWordEndAt(Sci::Position pos) const {
|
|
|
|
if (pos <= 0)
|
|
|
|
return false;
|
2022-01-04 23:07:50 +00:00
|
|
|
if (pos <= LengthNoExcept()) {
|
|
|
|
// At end of document, treat as if space after so can be word end
|
|
|
|
const CharacterExtracted cePos = (pos < LengthNoExcept()) ?
|
|
|
|
CharacterAfter(pos) : CharacterExtracted(' ', 1);
|
2019-05-04 18:14:48 +00:00
|
|
|
const CharacterExtracted cePrev = CharacterBefore(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
return IsWordEdge(WordCharacterClass(cePrev.character), WordCharacterClass(cePos.character));
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check that the given range is has transitions between character classes at both
|
|
|
|
* ends and where the characters on the inside are word or punctuation characters.
|
|
|
|
*/
|
2019-05-04 18:14:48 +00:00
|
|
|
bool Document::IsWordAt(Sci::Position start, Sci::Position end) const {
|
|
|
|
return (start < end) && IsWordStartAt(start) && IsWordEndAt(end);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
bool Document::MatchesWordOptions(bool word, bool wordStart, Sci::Position pos, Sci::Position length) const {
|
2013-08-28 00:44:27 +00:00
|
|
|
return (!word && !wordStart) ||
|
|
|
|
(word && IsWordAt(pos, pos + length)) ||
|
|
|
|
(wordStart && IsWordStartAt(pos));
|
2010-07-12 22:19:51 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
bool Document::HasCaseFolder() const noexcept {
|
|
|
|
return pcf != nullptr;
|
2010-07-12 22:19:51 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
void Document::SetCaseFolder(std::unique_ptr<CaseFolder> pcf_) noexcept {
|
|
|
|
pcf = std::move(pcf_);
|
2010-07-12 22:19:51 +00:00
|
|
|
}
|
|
|
|
|
2022-12-10 12:35:16 +00:00
|
|
|
CharacterExtracted Document::ExtractCharacter(Sci::Position position) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
const unsigned char leadByte = cb.UCharAt(position);
|
2015-06-07 21:19:26 +00:00
|
|
|
if (UTF8IsAscii(leadByte)) {
|
|
|
|
// Common case: ASCII character
|
|
|
|
return CharacterExtracted(leadByte, 1);
|
|
|
|
}
|
|
|
|
const int widthCharBytes = UTF8BytesOfLead[leadByte];
|
|
|
|
unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 };
|
|
|
|
for (int b=1; b<widthCharBytes; b++)
|
2019-05-04 18:14:48 +00:00
|
|
|
charBytes[b] = cb.UCharAt(position + b);
|
2022-12-10 12:35:16 +00:00
|
|
|
return CharacterExtracted(charBytes, widthCharBytes);
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
// Equivalent of memchr over the split view
|
|
|
|
ptrdiff_t SplitFindChar(const SplitView &view, size_t start, size_t length, int ch) noexcept {
|
|
|
|
size_t range1Length = 0;
|
|
|
|
if (start < view.length1) {
|
|
|
|
range1Length = std::min(length, view.length1 - start);
|
|
|
|
const char *match = static_cast<const char *>(memchr(view.segment1 + start, ch, range1Length));
|
|
|
|
if (match) {
|
|
|
|
return match - view.segment1;
|
|
|
|
}
|
|
|
|
start += range1Length;
|
|
|
|
}
|
|
|
|
const char *match2 = static_cast<const char *>(memchr(view.segment2 + start, ch, length - range1Length));
|
|
|
|
if (match2) {
|
|
|
|
return match2 - view.segment2;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Equivalent of memcmp over the split view
|
|
|
|
// This does not call memcmp as search texts are commonly too short to overcome the
|
|
|
|
// call overhead.
|
|
|
|
bool SplitMatch(const SplitView &view, size_t start, std::string_view text) noexcept {
|
|
|
|
for (size_t i = 0; i < text.length(); i++) {
|
|
|
|
if (view.CharAt(i + start) != text[i]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-04-24 23:35:41 +00:00
|
|
|
/**
|
|
|
|
* Find text in document, supporting both forward and backward
|
|
|
|
* searches (just pass minPos > maxPos to do a backward search)
|
|
|
|
* Has not been tested with backwards DBCS searches yet.
|
|
|
|
*/
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, const char *search,
|
2022-01-04 23:07:50 +00:00
|
|
|
FindOption flags, Sci::Position *length) {
|
2010-08-21 23:59:56 +00:00
|
|
|
if (*length <= 0)
|
|
|
|
return minPos;
|
2022-01-04 23:07:50 +00:00
|
|
|
const bool caseSensitive = FlagSet(flags, FindOption::MatchCase);
|
|
|
|
const bool word = FlagSet(flags, FindOption::WholeWord);
|
|
|
|
const bool wordStart = FlagSet(flags, FindOption::WordStart);
|
|
|
|
const bool regExp = FlagSet(flags, FindOption::RegExp);
|
2009-04-24 23:35:41 +00:00
|
|
|
if (regExp) {
|
2009-04-25 23:38:15 +00:00
|
|
|
if (!regex)
|
2019-05-04 18:14:48 +00:00
|
|
|
regex = std::unique_ptr<RegexSearchBase>(CreateRegexSearch(&charClass));
|
2010-07-12 22:19:51 +00:00
|
|
|
return regex->FindText(this, minPos, maxPos, search, caseSensitive, word, wordStart, flags, length);
|
2009-04-24 23:35:41 +00:00
|
|
|
} else {
|
|
|
|
|
2010-07-12 22:19:51 +00:00
|
|
|
const bool forward = minPos <= maxPos;
|
|
|
|
const int increment = forward ? 1 : -1;
|
2009-04-24 23:35:41 +00:00
|
|
|
|
|
|
|
// Range endpoints should not be inside DBCS characters, but just in case, move them.
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position startPos = MovePositionOutsideChar(minPos, increment, false);
|
|
|
|
const Sci::Position endPos = MovePositionOutsideChar(maxPos, increment, false);
|
2009-04-24 23:35:41 +00:00
|
|
|
|
|
|
|
// Compute actual search ranges needed
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position lengthFind = *length;
|
2009-12-02 02:24:37 +00:00
|
|
|
|
2010-07-12 22:19:51 +00:00
|
|
|
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position limitPos = std::max(startPos, endPos);
|
|
|
|
Sci::Position pos = startPos;
|
2011-03-22 00:16:49 +00:00
|
|
|
if (!forward) {
|
|
|
|
// Back all of a character
|
|
|
|
pos = NextPosition(pos, increment);
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
const SplitView cbView = cb.AllView();
|
2010-07-12 22:19:51 +00:00
|
|
|
if (caseSensitive) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
|
2022-01-04 23:07:50 +00:00
|
|
|
const unsigned char charStartSearch = search[0];
|
|
|
|
if (forward && ((0 == dbcsCodePage) || (CpUtf8 == dbcsCodePage && !UTF8IsTrailByte(charStartSearch)))) {
|
|
|
|
// This is a fast case where there is no need to test byte values to iterate
|
|
|
|
// so becomes the equivalent of a memchr+memcmp loop.
|
|
|
|
// UTF-8 search will not be self-synchronizing when starts with trail byte
|
|
|
|
const std::string_view suffix(search + 1, lengthFind - 1);
|
|
|
|
while (pos < endSearch) {
|
|
|
|
pos = SplitFindChar(cbView, pos, limitPos - pos, charStartSearch);
|
|
|
|
if (pos < 0) {
|
|
|
|
break;
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
if (SplitMatch(cbView, pos + 1, suffix) && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
|
2013-08-28 00:44:27 +00:00
|
|
|
return pos;
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
|
|
|
|
const unsigned char leadByte = cbView.CharAt(pos);
|
|
|
|
if (leadByte == charStartSearch) {
|
|
|
|
bool found = (pos + lengthFind) <= limitPos;
|
|
|
|
// SplitMatch could be called here but it is slower with g++ -O2
|
|
|
|
for (int indexSearch = 1; (indexSearch < lengthFind) && found; indexSearch++) {
|
|
|
|
found = cbView.CharAt(pos + indexSearch) == search[indexSearch];
|
|
|
|
}
|
|
|
|
if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (forward && UTF8IsAscii(leadByte)) {
|
|
|
|
pos++;
|
|
|
|
} else {
|
|
|
|
if (dbcsCodePage) {
|
|
|
|
if (!NextCharacter(pos, increment)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pos += increment;
|
|
|
|
}
|
|
|
|
}
|
2009-12-02 02:24:37 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (CpUtf8 == dbcsCodePage) {
|
2021-02-21 04:53:09 +00:00
|
|
|
constexpr size_t maxFoldingExpansion = 4;
|
2019-05-04 18:14:48 +00:00
|
|
|
std::vector<char> searchThing((lengthFind+1) * UTF8MaxBytes * maxFoldingExpansion + 1);
|
|
|
|
const size_t lenSearch =
|
|
|
|
pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
|
2013-08-28 00:44:27 +00:00
|
|
|
while (forward ? (pos < endPos) : (pos >= endPos)) {
|
2022-12-10 12:35:16 +00:00
|
|
|
int widthFirstCharacter = 1;
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position posIndexDocument = pos;
|
|
|
|
size_t indexSearch = 0;
|
2010-07-12 22:19:51 +00:00
|
|
|
bool characterMatches = true;
|
2022-12-10 12:35:16 +00:00
|
|
|
while (indexSearch < lenSearch) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const unsigned char leadByte = cbView.CharAt(posIndexDocument);
|
2013-08-28 00:44:27 +00:00
|
|
|
int widthChar = 1;
|
2022-01-04 23:07:50 +00:00
|
|
|
size_t lenFlat = 1;
|
2022-12-10 12:35:16 +00:00
|
|
|
if (UTF8IsAscii(leadByte)) {
|
|
|
|
if ((posIndexDocument + 1) > limitPos) {
|
|
|
|
break;
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
characterMatches = searchThing[indexSearch] == MakeLowerCase(leadByte);
|
|
|
|
} else {
|
2022-12-10 12:35:16 +00:00
|
|
|
char bytes[UTF8MaxBytes]{ static_cast<char>(leadByte) };
|
|
|
|
const int widthCharBytes = UTF8BytesOfLead[leadByte];
|
|
|
|
for (int b = 1; b < widthCharBytes; b++) {
|
|
|
|
bytes[b] = cbView.CharAt(posIndexDocument + b);
|
|
|
|
}
|
Updated to Scintilla 5.4.2 & Lexilla 5.3.1
https://www.scintilla.org/scintilla542.zip
Release 5.4.2
Released 5 March 2024.
Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
Add APIs for saving and restoring undo history.
For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
https://www.scintilla.org/lexilla531.zip
Release 5.3.1
Released 5 March 2024.
Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
Batch: Fix handling ':' next to keywords. Issue #222.
JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
2024-03-06 21:05:54 +00:00
|
|
|
widthChar = UTF8Classify(bytes, widthCharBytes) & UTF8MaskWidth;
|
2022-12-10 12:35:16 +00:00
|
|
|
if (!indexSearch) { // First character
|
|
|
|
widthFirstCharacter = widthChar;
|
|
|
|
}
|
|
|
|
if ((posIndexDocument + widthChar) > limitPos) {
|
|
|
|
break;
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
char folded[UTF8MaxBytes * maxFoldingExpansion + 1];
|
|
|
|
lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
|
|
|
|
// memcmp may examine lenFlat bytes in both arguments so assert it doesn't read past end of searchThing
|
|
|
|
assert((indexSearch + lenFlat) <= searchThing.size());
|
|
|
|
// Does folded match the buffer
|
|
|
|
characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
|
|
|
|
}
|
|
|
|
if (!characterMatches) {
|
2013-08-28 00:44:27 +00:00
|
|
|
break;
|
2022-01-04 23:07:50 +00:00
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
posIndexDocument += widthChar;
|
2010-07-12 22:19:51 +00:00
|
|
|
indexSearch += lenFlat;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
if (characterMatches && (indexSearch == lenSearch)) {
|
2013-08-28 00:44:27 +00:00
|
|
|
if (MatchesWordOptions(word, wordStart, pos, posIndexDocument - pos)) {
|
|
|
|
*length = posIndexDocument - pos;
|
2010-07-12 22:19:51 +00:00
|
|
|
return pos;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
2010-07-12 22:19:51 +00:00
|
|
|
}
|
|
|
|
if (forward) {
|
|
|
|
pos += widthFirstCharacter;
|
|
|
|
} else {
|
2022-01-04 23:07:50 +00:00
|
|
|
if (!NextCharacter(pos, increment)) {
|
2010-09-05 22:56:27 +00:00
|
|
|
break;
|
2022-01-04 23:07:50 +00:00
|
|
|
}
|
2010-09-05 22:56:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (dbcsCodePage) {
|
2021-02-21 04:53:09 +00:00
|
|
|
constexpr size_t maxBytesCharacter = 2;
|
|
|
|
constexpr size_t maxFoldingExpansion = 4;
|
2019-05-04 18:14:48 +00:00
|
|
|
std::vector<char> searchThing((lengthFind+1) * maxBytesCharacter * maxFoldingExpansion + 1);
|
|
|
|
const size_t lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
|
2013-08-28 00:44:27 +00:00
|
|
|
while (forward ? (pos < endPos) : (pos >= endPos)) {
|
2022-01-04 23:07:50 +00:00
|
|
|
int widthFirstCharacter = 0;
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position indexDocument = 0;
|
|
|
|
size_t indexSearch = 0;
|
2010-09-05 22:56:27 +00:00
|
|
|
bool characterMatches = true;
|
2022-01-04 23:07:50 +00:00
|
|
|
while (((pos + indexDocument) < limitPos) &&
|
2010-09-05 22:56:27 +00:00
|
|
|
(indexSearch < lenSearch)) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const unsigned char leadByte = cbView.CharAt(pos + indexDocument);
|
|
|
|
const int widthChar = (!UTF8IsAscii(leadByte) && IsDBCSLeadByteNoExcept(leadByte)) ? 2 : 1;
|
|
|
|
if (!widthFirstCharacter) {
|
|
|
|
widthFirstCharacter = widthChar;
|
|
|
|
}
|
|
|
|
if ((pos + indexDocument + widthChar) > limitPos) {
|
2013-08-28 00:44:27 +00:00
|
|
|
break;
|
2022-01-04 23:07:50 +00:00
|
|
|
}
|
|
|
|
size_t lenFlat = 1;
|
|
|
|
if (widthChar == 1) {
|
|
|
|
characterMatches = searchThing[indexSearch] == MakeLowerCase(leadByte);
|
|
|
|
} else {
|
2022-12-10 12:35:16 +00:00
|
|
|
const char bytes[maxBytesCharacter + 1] {
|
|
|
|
static_cast<char>(leadByte),
|
|
|
|
cbView.CharAt(pos + indexDocument + 1)
|
|
|
|
};
|
2022-01-04 23:07:50 +00:00
|
|
|
char folded[maxBytesCharacter * maxFoldingExpansion + 1];
|
|
|
|
lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
|
|
|
|
// memcmp may examine lenFlat bytes in both arguments so assert it doesn't read past end of searchThing
|
|
|
|
assert((indexSearch + lenFlat) <= searchThing.size());
|
|
|
|
// Does folded match the buffer
|
|
|
|
characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
|
|
|
|
}
|
|
|
|
if (!characterMatches) {
|
|
|
|
break;
|
|
|
|
}
|
2010-09-05 22:56:27 +00:00
|
|
|
indexDocument += widthChar;
|
|
|
|
indexSearch += lenFlat;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
if (characterMatches && (indexSearch == lenSearch)) {
|
2010-09-05 22:56:27 +00:00
|
|
|
if (MatchesWordOptions(word, wordStart, pos, indexDocument)) {
|
|
|
|
*length = indexDocument;
|
|
|
|
return pos;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
if (forward) {
|
|
|
|
pos += widthFirstCharacter;
|
|
|
|
} else {
|
|
|
|
if (!NextCharacter(pos, increment)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
2010-07-12 22:19:51 +00:00
|
|
|
} else {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
|
2010-07-12 22:19:51 +00:00
|
|
|
std::vector<char> searchThing(lengthFind + 1);
|
|
|
|
pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
|
|
|
|
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
|
|
|
|
bool found = (pos + lengthFind) <= limitPos;
|
|
|
|
for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const char ch = cbView.CharAt(pos + indexSearch);
|
|
|
|
const char chTest = searchThing[indexSearch];
|
|
|
|
if (UTF8IsAscii(ch)) {
|
|
|
|
found = chTest == MakeLowerCase(ch);
|
|
|
|
} else {
|
|
|
|
char folded[2];
|
|
|
|
pcf->Fold(folded, sizeof(folded), &ch, 1);
|
|
|
|
found = folded[0] == chTest;
|
|
|
|
}
|
2010-07-12 22:19:51 +00:00
|
|
|
}
|
|
|
|
if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
|
|
|
|
return pos;
|
|
|
|
}
|
2022-01-04 23:07:50 +00:00
|
|
|
pos += increment;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//Platform::DebugPrintf("Not found\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
const char *Document::SubstituteByPosition(const char *text, Sci::Position *length) {
|
2010-09-05 22:56:27 +00:00
|
|
|
if (regex)
|
|
|
|
return regex->SubstituteByPosition(this, text, length);
|
|
|
|
else
|
2019-05-04 18:14:48 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
LineCharacterIndexType Document::LineCharacterIndex() const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
return cb.LineCharacterIndex();
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
void Document::AllocateLineCharacterIndex(LineCharacterIndexType lineCharacterIndex) {
|
2019-05-04 18:14:48 +00:00
|
|
|
return cb.AllocateLineCharacterIndex(lineCharacterIndex);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
void Document::ReleaseLineCharacterIndex(LineCharacterIndexType lineCharacterIndex) {
|
2019-05-04 18:14:48 +00:00
|
|
|
return cb.ReleaseLineCharacterIndex(lineCharacterIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
Sci::Line Document::LinesTotal() const noexcept {
|
2009-04-24 23:35:41 +00:00
|
|
|
return cb.Lines();
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
void Document::AllocateLines(Sci::Line lines) {
|
|
|
|
cb.AllocateLines(lines);
|
|
|
|
}
|
|
|
|
|
2009-04-24 23:35:41 +00:00
|
|
|
void Document::SetDefaultCharClasses(bool includeWordClass) {
|
Update to scintilla 5.4.3 (from 5.4.1) & Lexilla 5.3.1
Sintilla [Release 5.4.3](https://www.scintilla.org/scintilla543.zip)
* Release 5.4.3: Released 9 March 2024
1. Fix redo failure introduced with 5.4.2. [Bug #2432](https://sourceforge.net/p/scintilla/bugs/2432/).
2. Add SC_AUTOCOMPLETE_SELECT_FIRST_ITEM option to always selects the first item in the autocompletion list. [Bug #2403](https://sourceforge.net/p/scintilla/bugs/2403/).
* Release 5.4.2: Released 5 March 2024
1. Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
2. Add APIs for saving and restoring undo history.
3. For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
4. For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
5. For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
6. For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
Lexilla [Release 5.3.1](https://www.scintilla.org/lexilla531.zip)
* Release 5.3.1: Released 5 March 2024
1. Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
2. Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
3. Batch: Fix handling ':' next to keywords. Issue #222.
4. JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
5. Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
6. Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
Close #14834
2024-03-10 22:19:01 +00:00
|
|
|
charClass.SetDefaultCharClasses(includeWordClass);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
void Document::SetCharClasses(const unsigned char *chars, CharacterClass newCharClass) {
|
Update to scintilla 5.4.3 (from 5.4.1) & Lexilla 5.3.1
Sintilla [Release 5.4.3](https://www.scintilla.org/scintilla543.zip)
* Release 5.4.3: Released 9 March 2024
1. Fix redo failure introduced with 5.4.2. [Bug #2432](https://sourceforge.net/p/scintilla/bugs/2432/).
2. Add SC_AUTOCOMPLETE_SELECT_FIRST_ITEM option to always selects the first item in the autocompletion list. [Bug #2403](https://sourceforge.net/p/scintilla/bugs/2403/).
* Release 5.4.2: Released 5 March 2024
1. Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
2. Add APIs for saving and restoring undo history.
3. For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
4. For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
5. For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
6. For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
Lexilla [Release 5.3.1](https://www.scintilla.org/lexilla531.zip)
* Release 5.3.1: Released 5 March 2024
1. Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
2. Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
3. Batch: Fix handling ':' next to keywords. Issue #222.
4. JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
5. Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
6. Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
Close #14834
2024-03-10 22:19:01 +00:00
|
|
|
charClass.SetCharClasses(chars, newCharClass);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
int Document::GetCharsOfClass(CharacterClass characterClass, unsigned char *buffer) const {
|
Update to scintilla 5.4.3 (from 5.4.1) & Lexilla 5.3.1
Sintilla [Release 5.4.3](https://www.scintilla.org/scintilla543.zip)
* Release 5.4.3: Released 9 March 2024
1. Fix redo failure introduced with 5.4.2. [Bug #2432](https://sourceforge.net/p/scintilla/bugs/2432/).
2. Add SC_AUTOCOMPLETE_SELECT_FIRST_ITEM option to always selects the first item in the autocompletion list. [Bug #2403](https://sourceforge.net/p/scintilla/bugs/2403/).
* Release 5.4.2: Released 5 March 2024
1. Significantly reduce memory used for undo actions, often to a half or quarter of previous versions. Feature #1458.
2. Add APIs for saving and restoring undo history.
3. For GTK, when laying out text, detect runs with both left-to-right and right-to-left ranges and divide into an ASCII prefix and more complex suffix. Lay out the ASCII prefix in the standard manner but, for the suffix, measure the whole width and spread that over the suffix bytes. This produces more usable results where the caret moves over the ASCII prefix correctly and over the suffix reasonably but not accurately.
4. For ScintillaEdit on Qt, fix reference from ScintillaDocument to Document to match change in 5.4.1 using IDocumentEditable for SCI_GETDOCPOINTER and SCI_SETDOCPOINTER.
5. For Direct2D on Win32, use the multi-threaded option to avoid crashes when Scintilla instances created on different threads. There may be more problems with this scenario so it should be avoided. Bug #2420.
6. For Win32, ensure keyboard-initiated context menu appears in multi-screen situations.
Lexilla [Release 5.3.1](https://www.scintilla.org/lexilla531.zip)
* Release 5.3.1: Released 5 March 2024
1. Assembler: After comments, treat \r\n line ends the same as \n. This makes testing easier.
2. Bash: Fix folding when line changed to/from comment and previous line is comment. Issue #224.
3. Batch: Fix handling ':' next to keywords. Issue #222.
4. JavaScript: in cpp lexer, add lexer.cpp.backquoted.strings=2 mode to treat ` back-quoted strings as template literals which allow embedded ${expressions}. Issue #94.
5. Python: fix lexing of rb'' and rf'' strings. Issue #223, Pull request #227.
6. Ruby: fix lexing of methods on numeric literals like '3.times' so the '.' and method name do not appear in numeric style. Issue #225.
Close #14834
2024-03-10 22:19:01 +00:00
|
|
|
return charClass.GetCharsOfClass(characterClass, buffer);
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
void Document::SetCharacterCategoryOptimization(int countCharacters) {
|
|
|
|
charMap.Optimize(countCharacters);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Document::CharacterCategoryOptimization() const noexcept {
|
|
|
|
return charMap.Size();
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void SCI_METHOD Document::StartStyling(Sci_Position position) {
|
2009-04-24 23:35:41 +00:00
|
|
|
endStyled = position;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
bool SCI_METHOD Document::SetStyleFor(Sci_Position length, char style) {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (enteredStyling != 0) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
enteredStyling++;
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position prevEndStyled = endStyled;
|
2015-06-07 21:19:26 +00:00
|
|
|
if (cb.SetStyleFor(endStyled, length, style)) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User,
|
2009-04-24 23:35:41 +00:00
|
|
|
prevEndStyled, length);
|
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
endStyled += length;
|
|
|
|
enteredStyling--;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
bool SCI_METHOD Document::SetStyles(Sci_Position length, const char *styles) {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (enteredStyling != 0) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
enteredStyling++;
|
|
|
|
bool didChange = false;
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position startMod = 0;
|
|
|
|
Sci::Position endMod = 0;
|
2009-04-24 23:35:41 +00:00
|
|
|
for (int iPos = 0; iPos < length; iPos++, endStyled++) {
|
|
|
|
PLATFORM_ASSERT(endStyled < Length());
|
2015-06-07 21:19:26 +00:00
|
|
|
if (cb.SetStyleAt(endStyled, styles[iPos])) {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (!didChange) {
|
|
|
|
startMod = endStyled;
|
|
|
|
}
|
|
|
|
didChange = true;
|
|
|
|
endMod = endStyled;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (didChange) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User,
|
2009-04-24 23:35:41 +00:00
|
|
|
startMod, endMod - startMod + 1);
|
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
enteredStyling--;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::EnsureStyledTo(Sci::Position pos) {
|
2009-04-24 23:35:41 +00:00
|
|
|
if ((enteredStyling == 0) && (pos > GetEndStyled())) {
|
|
|
|
IncrementStyleClock();
|
2010-08-21 23:59:56 +00:00
|
|
|
if (pli && !pli->UseContainerLexing()) {
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
const Sci::Position endStyledTo = LineStartPosition(GetEndStyled());
|
2011-03-22 00:16:49 +00:00
|
|
|
pli->Colourise(endStyledTo, pos);
|
2010-08-21 23:59:56 +00:00
|
|
|
} else {
|
|
|
|
// Ask the watchers to style, and stop as soon as one responds.
|
2013-08-28 00:44:27 +00:00
|
|
|
for (std::vector<WatcherWithUserData>::iterator it = watchers.begin();
|
|
|
|
(pos > GetEndStyled()) && (it != watchers.end()); ++it) {
|
|
|
|
it->watcher->NotifyStyleNeeded(this, it->userData, pos);
|
2010-08-21 23:59:56 +00:00
|
|
|
}
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::StyleToAdjustingLineDuration(Sci::Position pos) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const Sci::Position stylingStart = GetEndStyled();
|
2019-05-04 18:14:48 +00:00
|
|
|
ElapsedPeriod epStyling;
|
|
|
|
EnsureStyledTo(pos);
|
2022-01-04 23:07:50 +00:00
|
|
|
durationStyleOneByte.AddSample(pos - stylingStart, epStyling.Duration());
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
LexInterface *Document::GetLexInterface() const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
return pli.get();
|
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
void Document::SetLexInterface(std::unique_ptr<LexInterface> pLexInterface) noexcept {
|
|
|
|
pli = std::move(pLexInterface);
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int SCI_METHOD Document::SetLineState(Sci_Position line, int state) {
|
2022-08-27 07:35:52 +00:00
|
|
|
const int statePrevious = States()->SetLineState(line, state, LinesTotal());
|
2009-04-24 23:35:41 +00:00
|
|
|
if (state != statePrevious) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeLineState, LineStart(line), 0, 0, nullptr,
|
2019-05-04 18:14:48 +00:00
|
|
|
static_cast<Sci::Line>(line));
|
2009-04-24 23:35:41 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
return statePrevious;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
int SCI_METHOD Document::GetLineState(Sci_Position line) const {
|
2021-02-21 04:53:09 +00:00
|
|
|
return States()->GetLineState(line);
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
Sci::Line Document::GetMaxLineState() const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
return States()->GetMaxLineState();
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void SCI_METHOD Document::ChangeLexerState(Sci_Position start, Sci_Position end) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::LexerState, start,
|
|
|
|
end-start, 0, nullptr, 0);
|
2010-08-21 23:59:56 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
StyledText Document::MarginStyledText(Sci::Line line) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
const LineAnnotation *pla = Margins();
|
2010-07-12 22:19:51 +00:00
|
|
|
return StyledText(pla->Length(line), pla->Text(line),
|
2009-06-24 19:09:31 +00:00
|
|
|
pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::MarginSetText(Sci::Line line, const char *text) {
|
|
|
|
Margins()->SetText(line, text);
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeMargin, LineStart(line),
|
|
|
|
0, 0, nullptr, line);
|
2009-06-24 19:09:31 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::MarginSetStyle(Sci::Line line, int style) {
|
|
|
|
Margins()->SetStyle(line, style);
|
2022-01-04 23:07:50 +00:00
|
|
|
NotifyModified(DocModification(ModificationFlags::ChangeMargin, LineStart(line),
|
|
|
|
0, 0, nullptr, line));
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::MarginSetStyles(Sci::Line line, const unsigned char *styles) {
|
|
|
|
Margins()->SetStyles(line, styles);
|
2022-01-04 23:07:50 +00:00
|
|
|
NotifyModified(DocModification(ModificationFlags::ChangeMargin, LineStart(line),
|
|
|
|
0, 0, nullptr, line));
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Document::MarginClearAll() {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line maxEditorLine = LinesTotal();
|
|
|
|
for (Sci::Line l=0; l<maxEditorLine; l++)
|
|
|
|
MarginSetText(l, nullptr);
|
2009-06-24 19:09:31 +00:00
|
|
|
// Free remaining data
|
2019-05-04 18:14:48 +00:00
|
|
|
Margins()->ClearAll();
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
StyledText Document::AnnotationStyledText(Sci::Line line) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
const LineAnnotation *pla = Annotations();
|
2010-07-12 22:19:51 +00:00
|
|
|
return StyledText(pla->Length(line), pla->Text(line),
|
2009-06-24 19:09:31 +00:00
|
|
|
pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::AnnotationSetText(Sci::Line line, const char *text) {
|
2013-08-28 00:44:27 +00:00
|
|
|
if (line >= 0 && line < LinesTotal()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line linesBefore = AnnotationLines(line);
|
|
|
|
Annotations()->SetText(line, text);
|
2013-08-28 00:44:27 +00:00
|
|
|
const int linesAfter = AnnotationLines(line);
|
2022-01-04 23:07:50 +00:00
|
|
|
DocModification mh(ModificationFlags::ChangeAnnotation, LineStart(line),
|
|
|
|
0, 0, nullptr, line);
|
2013-08-28 00:44:27 +00:00
|
|
|
mh.annotationLinesAdded = linesAfter - linesBefore;
|
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::AnnotationSetStyle(Sci::Line line, int style) {
|
2021-02-21 04:53:09 +00:00
|
|
|
if (line >= 0 && line < LinesTotal()) {
|
|
|
|
Annotations()->SetStyle(line, style);
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeAnnotation, LineStart(line),
|
|
|
|
0, 0, nullptr, line);
|
2021-02-21 04:53:09 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::AnnotationSetStyles(Sci::Line line, const unsigned char *styles) {
|
2013-08-28 00:44:27 +00:00
|
|
|
if (line >= 0 && line < LinesTotal()) {
|
2019-05-04 18:14:48 +00:00
|
|
|
Annotations()->SetStyles(line, styles);
|
2013-08-28 00:44:27 +00:00
|
|
|
}
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
int Document::AnnotationLines(Sci::Line line) const noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
return Annotations()->Lines(line);
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Document::AnnotationClearAll() {
|
2022-05-25 20:16:39 +00:00
|
|
|
if (Annotations()->Empty()) {
|
|
|
|
return;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Line maxEditorLine = LinesTotal();
|
|
|
|
for (Sci::Line l=0; l<maxEditorLine; l++)
|
|
|
|
AnnotationSetText(l, nullptr);
|
2009-06-24 19:09:31 +00:00
|
|
|
// Free remaining data
|
2019-05-04 18:14:48 +00:00
|
|
|
Annotations()->ClearAll();
|
2009-06-24 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2021-02-21 04:53:09 +00:00
|
|
|
StyledText Document::EOLAnnotationStyledText(Sci::Line line) const noexcept {
|
|
|
|
const LineAnnotation *pla = EOLAnnotations();
|
|
|
|
return StyledText(pla->Length(line), pla->Text(line),
|
|
|
|
pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::EOLAnnotationSetText(Sci::Line line, const char *text) {
|
|
|
|
if (line >= 0 && line < LinesTotal()) {
|
|
|
|
EOLAnnotations()->SetText(line, text);
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeEOLAnnotation, LineStart(line),
|
|
|
|
0, 0, nullptr, line);
|
2021-02-21 04:53:09 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::EOLAnnotationSetStyle(Sci::Line line, int style) {
|
|
|
|
if (line >= 0 && line < LinesTotal()) {
|
|
|
|
EOLAnnotations()->SetStyle(line, style);
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeEOLAnnotation, LineStart(line),
|
|
|
|
0, 0, nullptr, line);
|
2021-02-21 04:53:09 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::EOLAnnotationClearAll() {
|
2022-05-25 20:16:39 +00:00
|
|
|
if (EOLAnnotations()->Empty()) {
|
|
|
|
return;
|
|
|
|
}
|
2021-02-21 04:53:09 +00:00
|
|
|
const Sci::Line maxEditorLine = LinesTotal();
|
|
|
|
for (Sci::Line l=0; l<maxEditorLine; l++)
|
|
|
|
EOLAnnotationSetText(l, nullptr);
|
|
|
|
// Free remaining data
|
|
|
|
EOLAnnotations()->ClearAll();
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void Document::IncrementStyleClock() noexcept {
|
2009-04-24 23:35:41 +00:00
|
|
|
styleClock = (styleClock + 1) % 0x100000;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
void SCI_METHOD Document::DecorationSetCurrentIndicator(int indicator) {
|
|
|
|
decorations->SetCurrentIndicator(indicator);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SCI_METHOD Document::DecorationFillRange(Sci_Position position, int value, Sci_Position fillLength) {
|
|
|
|
const FillResult<Sci::Position> fr = decorations->FillRange(
|
|
|
|
position, value, fillLength);
|
|
|
|
if (fr.changed) {
|
2022-01-04 23:07:50 +00:00
|
|
|
const DocModification mh(ModificationFlags::ChangeIndicator | ModificationFlags::User,
|
2019-05-04 18:14:48 +00:00
|
|
|
fr.position, fr.fillLength);
|
2009-04-24 23:35:41 +00:00
|
|
|
NotifyModified(mh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Document::AddWatcher(DocWatcher *watcher, void *userData) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const WatcherWithUserData wwud(watcher, userData);
|
2015-06-07 21:19:26 +00:00
|
|
|
std::vector<WatcherWithUserData>::iterator it =
|
2013-08-28 00:44:27 +00:00
|
|
|
std::find(watchers.begin(), watchers.end(), wwud);
|
|
|
|
if (it != watchers.end())
|
|
|
|
return false;
|
|
|
|
watchers.push_back(wwud);
|
2009-04-24 23:35:41 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) noexcept {
|
|
|
|
try {
|
|
|
|
// This can never fail as WatcherWithUserData constructor and == are noexcept
|
|
|
|
// but std::find is not noexcept.
|
|
|
|
std::vector<WatcherWithUserData>::iterator it =
|
|
|
|
std::find(watchers.begin(), watchers.end(), WatcherWithUserData(watcher, userData));
|
|
|
|
if (it != watchers.end()) {
|
|
|
|
watchers.erase(it);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} catch (...) {
|
|
|
|
// Ignore any exception
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::NotifyModifyAttempt() {
|
2019-05-04 18:14:48 +00:00
|
|
|
for (const WatcherWithUserData &watcher : watchers) {
|
|
|
|
watcher.watcher->NotifyModifyAttempt(this, watcher.userData);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::NotifySavePoint(bool atSavePoint) {
|
2019-05-04 18:14:48 +00:00
|
|
|
for (const WatcherWithUserData &watcher : watchers) {
|
|
|
|
watcher.watcher->NotifySavePoint(this, watcher.userData, atSavePoint);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Document::NotifyModified(DocModification mh) {
|
2022-01-04 23:07:50 +00:00
|
|
|
if (FlagSet(mh.modificationType, ModificationFlags::InsertText)) {
|
2019-05-04 18:14:48 +00:00
|
|
|
decorations->InsertSpace(mh.position, mh.length);
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (FlagSet(mh.modificationType, ModificationFlags::DeleteText)) {
|
2019-05-04 18:14:48 +00:00
|
|
|
decorations->DeleteRange(mh.position, mh.length);
|
|
|
|
}
|
|
|
|
for (const WatcherWithUserData &watcher : watchers) {
|
|
|
|
watcher.watcher->NotifyModified(this, mh, watcher.userData);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Document::IsWordPartSeparator(unsigned int ch) const {
|
2022-01-04 23:07:50 +00:00
|
|
|
return (WordCharacterClass(ch) == CharacterClass::word) && IsPunctuation(ch);
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::WordPartLeft(Sci::Position pos) const {
|
2009-04-24 23:35:41 +00:00
|
|
|
if (pos > 0) {
|
2019-05-04 18:14:48 +00:00
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
|
|
|
CharacterExtracted ceStart = CharacterAfter(pos);
|
|
|
|
if (IsWordPartSeparator(ceStart.character)) {
|
|
|
|
while (pos > 0 && IsWordPartSeparator(CharacterAfter(pos).character)) {
|
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pos > 0) {
|
2019-05-04 18:14:48 +00:00
|
|
|
ceStart = CharacterAfter(pos);
|
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
|
|
|
if (IsLowerCase(ceStart.character)) {
|
|
|
|
while (pos > 0 && IsLowerCase(CharacterAfter(pos).character))
|
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
|
|
|
if (!IsUpperCase(CharacterAfter(pos).character) && !IsLowerCase(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
|
|
|
} else if (IsUpperCase(ceStart.character)) {
|
|
|
|
while (pos > 0 && IsUpperCase(CharacterAfter(pos).character))
|
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
|
|
|
if (!IsUpperCase(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
|
|
|
} else if (IsADigit(ceStart.character)) {
|
|
|
|
while (pos > 0 && IsADigit(CharacterAfter(pos).character))
|
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
|
|
|
if (!IsADigit(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (IsPunctuation(ceStart.character)) {
|
|
|
|
while (pos > 0 && IsPunctuation(CharacterAfter(pos).character))
|
2019-05-04 18:14:48 +00:00
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
2022-01-04 23:07:50 +00:00
|
|
|
if (!IsPunctuation(CharacterAfter(pos).character))
|
2019-05-04 18:14:48 +00:00
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (IsASpace(ceStart.character)) {
|
|
|
|
while (pos > 0 && IsASpace(CharacterAfter(pos).character))
|
2019-05-04 18:14:48 +00:00
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
2022-01-04 23:07:50 +00:00
|
|
|
if (!IsASpace(CharacterAfter(pos).character))
|
2019-05-04 18:14:48 +00:00
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
|
|
|
} else if (!IsASCII(ceStart.character)) {
|
|
|
|
while (pos > 0 && !IsASCII(CharacterAfter(pos).character))
|
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
|
|
|
if (IsASCII(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
} else {
|
2019-05-04 18:14:48 +00:00
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Document::WordPartRight(Sci::Position pos) const {
|
|
|
|
CharacterExtracted ceStart = CharacterAfter(pos);
|
2019-07-21 13:26:02 +00:00
|
|
|
const Sci::Position length = LengthNoExcept();
|
2019-05-04 18:14:48 +00:00
|
|
|
if (IsWordPartSeparator(ceStart.character)) {
|
|
|
|
while (pos < length && IsWordPartSeparator(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
|
|
|
ceStart = CharacterAfter(pos);
|
|
|
|
}
|
|
|
|
if (!IsASCII(ceStart.character)) {
|
|
|
|
while (pos < length && !IsASCII(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
|
|
|
} else if (IsLowerCase(ceStart.character)) {
|
|
|
|
while (pos < length && IsLowerCase(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
|
|
|
} else if (IsUpperCase(ceStart.character)) {
|
|
|
|
if (IsLowerCase(CharacterAfter(pos + ceStart.widthBytes).character)) {
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
|
|
|
while (pos < length && IsLowerCase(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
} else {
|
2019-05-04 18:14:48 +00:00
|
|
|
while (pos < length && IsUpperCase(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
|
|
|
}
|
|
|
|
if (IsLowerCase(CharacterAfter(pos).character) && IsUpperCase(CharacterBefore(pos).character))
|
|
|
|
pos -= CharacterBefore(pos).widthBytes;
|
|
|
|
} else if (IsADigit(ceStart.character)) {
|
|
|
|
while (pos < length && IsADigit(CharacterAfter(pos).character))
|
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (IsPunctuation(ceStart.character)) {
|
|
|
|
while (pos < length && IsPunctuation(CharacterAfter(pos).character))
|
2019-05-04 18:14:48 +00:00
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
2022-01-04 23:07:50 +00:00
|
|
|
} else if (IsASpace(ceStart.character)) {
|
|
|
|
while (pos < length && IsASpace(CharacterAfter(pos).character))
|
2019-05-04 18:14:48 +00:00
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
} else {
|
2019-05-04 18:14:48 +00:00
|
|
|
pos += CharacterAfter(pos).widthBytes;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2019-07-21 13:26:02 +00:00
|
|
|
Sci::Position Document::ExtendStyleRange(Sci::Position pos, int delta, bool singleLine) noexcept {
|
2022-01-04 23:07:50 +00:00
|
|
|
const char sStart = cb.StyleAt(pos);
|
2009-04-24 23:35:41 +00:00
|
|
|
if (delta < 0) {
|
2022-01-04 23:07:50 +00:00
|
|
|
while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsEOLCharacter(cb.CharAt(pos))))
|
2009-04-24 23:35:41 +00:00
|
|
|
pos--;
|
|
|
|
pos++;
|
|
|
|
} else {
|
2022-01-04 23:07:50 +00:00
|
|
|
while (pos < (LengthNoExcept()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsEOLCharacter(cb.CharAt(pos))))
|
2009-04-24 23:35:41 +00:00
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
static char BraceOpposite(char ch) noexcept {
|
2009-04-24 23:35:41 +00:00
|
|
|
switch (ch) {
|
|
|
|
case '(':
|
|
|
|
return ')';
|
|
|
|
case ')':
|
|
|
|
return '(';
|
|
|
|
case '[':
|
|
|
|
return ']';
|
|
|
|
case ']':
|
|
|
|
return '[';
|
|
|
|
case '{':
|
|
|
|
return '}';
|
|
|
|
case '}':
|
|
|
|
return '{';
|
|
|
|
case '<':
|
|
|
|
return '>';
|
|
|
|
case '>':
|
|
|
|
return '<';
|
|
|
|
default:
|
|
|
|
return '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: should be able to extend styled region to find matching brace
|
2021-02-21 04:53:09 +00:00
|
|
|
Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxReStyle*/, Sci::Position startPos, bool useStartPos) noexcept {
|
2019-05-04 18:14:48 +00:00
|
|
|
const char chBrace = CharAt(position);
|
|
|
|
const char chSeek = BraceOpposite(chBrace);
|
2009-04-24 23:35:41 +00:00
|
|
|
if (chSeek == '\0')
|
|
|
|
return - 1;
|
2019-05-04 18:14:48 +00:00
|
|
|
const int styBrace = StyleIndexAt(position);
|
2009-04-24 23:35:41 +00:00
|
|
|
int direction = -1;
|
|
|
|
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
|
|
|
|
direction = 1;
|
|
|
|
int depth = 1;
|
2021-02-21 04:53:09 +00:00
|
|
|
position = useStartPos ? startPos : NextPosition(position, direction);
|
2019-07-21 13:26:02 +00:00
|
|
|
while ((position >= 0) && (position < LengthNoExcept())) {
|
2019-05-04 18:14:48 +00:00
|
|
|
const char chAtPos = CharAt(position);
|
|
|
|
const int styAtPos = StyleIndexAt(position);
|
2009-04-24 23:35:41 +00:00
|
|
|
if ((position > GetEndStyled()) || (styAtPos == styBrace)) {
|
|
|
|
if (chAtPos == chBrace)
|
|
|
|
depth++;
|
|
|
|
if (chAtPos == chSeek)
|
|
|
|
depth--;
|
|
|
|
if (depth == 0)
|
|
|
|
return position;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
const Sci::Position positionBeforeMove = position;
|
2010-09-05 22:56:27 +00:00
|
|
|
position = NextPosition(position, direction);
|
|
|
|
if (position == positionBeforeMove)
|
|
|
|
break;
|
2009-04-24 23:35:41 +00:00
|
|
|
}
|
|
|
|
return - 1;
|
|
|
|
}
|
2009-04-25 23:38:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementation of RegexSearchBase for the default built-in regular expression engine
|
|
|
|
*/
|
|
|
|
class BuiltinRegex : public RegexSearchBase {
|
|
|
|
public:
|
2015-06-07 21:19:26 +00:00
|
|
|
explicit BuiltinRegex(CharClassify *charClassTable) : search(charClassTable) {}
|
2009-04-25 23:38:15 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position FindText(Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s,
|
2022-01-04 23:07:50 +00:00
|
|
|
bool caseSensitive, bool word, bool wordStart, FindOption flags,
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position *length) override;
|
2009-04-25 23:38:15 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
const char *SubstituteByPosition(Document *doc, const char *text, Sci::Position *length) override;
|
2009-04-25 23:38:15 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
RESearch search;
|
2013-08-28 00:44:27 +00:00
|
|
|
std::string substituted;
|
2009-04-25 23:38:15 +00:00
|
|
|
};
|
|
|
|
|
2015-06-07 21:19:26 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* RESearchRange keeps track of search range.
|
|
|
|
*/
|
|
|
|
class RESearchRange {
|
|
|
|
public:
|
|
|
|
const Document *doc;
|
|
|
|
int increment;
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position startPos;
|
|
|
|
Sci::Position endPos;
|
|
|
|
Sci::Line lineRangeStart;
|
|
|
|
Sci::Line lineRangeEnd;
|
|
|
|
Sci::Line lineRangeBreak;
|
2019-07-21 13:26:02 +00:00
|
|
|
RESearchRange(const Document *doc_, Sci::Position minPos, Sci::Position maxPos) noexcept : doc(doc_) {
|
2015-06-07 21:19:26 +00:00
|
|
|
increment = (minPos <= maxPos) ? 1 : -1;
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
// Range endpoints should not be inside DBCS characters or between a CR and LF,
|
|
|
|
// but just in case, move them.
|
|
|
|
startPos = doc->MovePositionOutsideChar(minPos, 1, true);
|
|
|
|
endPos = doc->MovePositionOutsideChar(maxPos, 1, true);
|
|
|
|
|
|
|
|
lineRangeStart = doc->SciLineFromPosition(startPos);
|
|
|
|
lineRangeEnd = doc->SciLineFromPosition(endPos);
|
2015-06-07 21:19:26 +00:00
|
|
|
lineRangeBreak = lineRangeEnd + increment;
|
|
|
|
}
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
Range LineRange(Sci::Line line, Sci::Position lineStartPos, Sci::Position lineEndPos) const noexcept {
|
|
|
|
Range range(lineStartPos, lineEndPos);
|
2015-06-07 21:19:26 +00:00
|
|
|
if (increment == 1) {
|
|
|
|
if (line == lineRangeStart)
|
|
|
|
range.start = startPos;
|
|
|
|
if (line == lineRangeEnd)
|
|
|
|
range.end = endPos;
|
|
|
|
} else {
|
|
|
|
if (line == lineRangeEnd)
|
|
|
|
range.start = endPos;
|
|
|
|
if (line == lineRangeStart)
|
|
|
|
range.end = startPos;
|
|
|
|
}
|
|
|
|
return range;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-04-25 23:38:15 +00:00
|
|
|
// Define a way for the Regular Expression code to access the document
|
2023-05-31 23:11:12 +00:00
|
|
|
class DocumentIndexer final : public CharacterIndexer {
|
2009-04-25 23:38:15 +00:00
|
|
|
Document *pdoc;
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position end;
|
2009-04-25 23:38:15 +00:00
|
|
|
public:
|
2019-05-04 18:14:48 +00:00
|
|
|
DocumentIndexer(Document *pdoc_, Sci::Position end_) noexcept :
|
2009-04-25 23:38:15 +00:00
|
|
|
pdoc(pdoc_), end(end_) {
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
char CharAt(Sci::Position index) const noexcept override {
|
2009-04-25 23:38:15 +00:00
|
|
|
if (index < 0 || index >= end)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return pdoc->CharAt(index);
|
|
|
|
}
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir) const noexcept override {
|
|
|
|
return pdoc->MovePositionOutsideChar(pos, moveDir, false);
|
|
|
|
}
|
2009-04-25 23:38:15 +00:00
|
|
|
};
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
#ifndef NO_CXX11_REGEX
|
2015-06-07 21:19:26 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
class ByteIterator {
|
2015-06-07 21:19:26 +00:00
|
|
|
public:
|
2022-01-04 23:07:50 +00:00
|
|
|
using iterator_category = std::bidirectional_iterator_tag;
|
|
|
|
using value_type = char;
|
|
|
|
using difference_type = ptrdiff_t;
|
|
|
|
using pointer = char*;
|
|
|
|
using reference = char&;
|
2019-05-04 18:14:48 +00:00
|
|
|
|
2015-06-07 21:19:26 +00:00
|
|
|
const Document *doc;
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position position;
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
explicit ByteIterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept :
|
2019-05-04 18:14:48 +00:00
|
|
|
doc(doc_), position(position_) {
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
char operator*() const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
return doc->CharAt(position);
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
ByteIterator &operator++() noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
position++;
|
|
|
|
return *this;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
ByteIterator operator++(int) noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
ByteIterator retVal(*this);
|
|
|
|
position++;
|
|
|
|
return retVal;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
ByteIterator &operator--() noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
position--;
|
|
|
|
return *this;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
bool operator==(const ByteIterator &other) const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
return doc == other.doc && position == other.position;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
bool operator!=(const ByteIterator &other) const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
return doc != other.doc || position != other.position;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Pos() const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
return position;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position PosRoundUp() const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
return position;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// On Windows, wchar_t is 16 bits wide and on Unix it is 32 bits wide.
|
|
|
|
// Would be better to use sizeof(wchar_t) or similar to differentiate
|
|
|
|
// but easier for now to hard-code platforms.
|
|
|
|
// C++11 has char16_t and char32_t but neither Clang nor Visual C++
|
|
|
|
// appear to allow specializing basic_regex over these.
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#define WCHAR_T_IS_16 1
|
|
|
|
#else
|
|
|
|
#define WCHAR_T_IS_16 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if WCHAR_T_IS_16
|
|
|
|
|
|
|
|
// On Windows, report non-BMP characters as 2 separate surrogates as that
|
|
|
|
// matches wregex since it is based on wchar_t.
|
2019-05-04 18:14:48 +00:00
|
|
|
class UTF8Iterator {
|
2015-06-07 21:19:26 +00:00
|
|
|
// These 3 fields determine the iterator position and are used for comparisons
|
|
|
|
const Document *doc;
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position position;
|
2015-06-07 21:19:26 +00:00
|
|
|
size_t characterIndex;
|
|
|
|
// Remaining fields are derived from the determining fields so are excluded in comparisons
|
|
|
|
unsigned int lenBytes;
|
|
|
|
size_t lenCharacters;
|
|
|
|
wchar_t buffered[2];
|
|
|
|
public:
|
2022-01-04 23:07:50 +00:00
|
|
|
using iterator_category = std::bidirectional_iterator_tag;
|
|
|
|
using value_type = wchar_t;
|
|
|
|
using difference_type = ptrdiff_t;
|
|
|
|
using pointer = wchar_t*;
|
|
|
|
using reference = wchar_t&;
|
2019-05-04 18:14:48 +00:00
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
explicit UTF8Iterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept :
|
2019-05-04 18:14:48 +00:00
|
|
|
doc(doc_), position(position_), characterIndex(0), lenBytes(0), lenCharacters(0), buffered{} {
|
2015-06-07 21:19:26 +00:00
|
|
|
buffered[0] = 0;
|
|
|
|
buffered[1] = 0;
|
|
|
|
if (doc) {
|
|
|
|
ReadCharacter();
|
|
|
|
}
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
wchar_t operator*() const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
assert(lenCharacters != 0);
|
|
|
|
return buffered[characterIndex];
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
UTF8Iterator &operator++() noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
if ((characterIndex + 1) < (lenCharacters)) {
|
|
|
|
characterIndex++;
|
|
|
|
} else {
|
|
|
|
position += lenBytes;
|
|
|
|
ReadCharacter();
|
|
|
|
characterIndex = 0;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
UTF8Iterator operator++(int) noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
UTF8Iterator retVal(*this);
|
|
|
|
if ((characterIndex + 1) < (lenCharacters)) {
|
|
|
|
characterIndex++;
|
|
|
|
} else {
|
|
|
|
position += lenBytes;
|
|
|
|
ReadCharacter();
|
|
|
|
characterIndex = 0;
|
|
|
|
}
|
|
|
|
return retVal;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
UTF8Iterator &operator--() noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
if (characterIndex) {
|
|
|
|
characterIndex--;
|
|
|
|
} else {
|
|
|
|
position = doc->NextPosition(position, -1);
|
|
|
|
ReadCharacter();
|
|
|
|
characterIndex = lenCharacters - 1;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
bool operator==(const UTF8Iterator &other) const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
// Only test the determining fields, not the character widths and values derived from this
|
|
|
|
return doc == other.doc &&
|
|
|
|
position == other.position &&
|
|
|
|
characterIndex == other.characterIndex;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
bool operator!=(const UTF8Iterator &other) const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
// Only test the determining fields, not the character widths and values derived from this
|
|
|
|
return doc != other.doc ||
|
|
|
|
position != other.position ||
|
|
|
|
characterIndex != other.characterIndex;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Pos() const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
return position;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position PosRoundUp() const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
if (characterIndex)
|
|
|
|
return position + lenBytes; // Force to end of character
|
|
|
|
else
|
|
|
|
return position;
|
|
|
|
}
|
|
|
|
private:
|
2019-05-04 18:14:48 +00:00
|
|
|
void ReadCharacter() noexcept {
|
2022-12-10 12:35:16 +00:00
|
|
|
const CharacterExtracted charExtracted = doc->ExtractCharacter(position);
|
2015-06-07 21:19:26 +00:00
|
|
|
lenBytes = charExtracted.widthBytes;
|
|
|
|
if (charExtracted.character == unicodeReplacementChar) {
|
|
|
|
lenCharacters = 1;
|
|
|
|
buffered[0] = static_cast<wchar_t>(charExtracted.character);
|
|
|
|
} else {
|
|
|
|
lenCharacters = UTF16FromUTF32Character(charExtracted.character, buffered);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
// On Unix, report non-BMP characters as single characters
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
class UTF8Iterator {
|
2015-06-07 21:19:26 +00:00
|
|
|
const Document *doc;
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position position;
|
2015-06-07 21:19:26 +00:00
|
|
|
public:
|
2022-01-04 23:07:50 +00:00
|
|
|
using iterator_category = std::bidirectional_iterator_tag;
|
|
|
|
using value_type = wchar_t;
|
|
|
|
using difference_type = ptrdiff_t;
|
|
|
|
using pointer = wchar_t*;
|
|
|
|
using reference = wchar_t&;
|
2019-05-04 18:14:48 +00:00
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
explicit UTF8Iterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept :
|
2019-05-04 18:14:48 +00:00
|
|
|
doc(doc_), position(position_) {
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
wchar_t operator*() const noexcept {
|
2022-12-10 12:35:16 +00:00
|
|
|
const CharacterExtracted charExtracted = doc->ExtractCharacter(position);
|
2015-06-07 21:19:26 +00:00
|
|
|
return charExtracted.character;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
UTF8Iterator &operator++() noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
position = doc->NextPosition(position, 1);
|
|
|
|
return *this;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
UTF8Iterator operator++(int) noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
UTF8Iterator retVal(*this);
|
|
|
|
position = doc->NextPosition(position, 1);
|
|
|
|
return retVal;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
UTF8Iterator &operator--() noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
position = doc->NextPosition(position, -1);
|
|
|
|
return *this;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
bool operator==(const UTF8Iterator &other) const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
return doc == other.doc && position == other.position;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
bool operator!=(const UTF8Iterator &other) const noexcept {
|
2015-06-07 21:19:26 +00:00
|
|
|
return doc != other.doc || position != other.position;
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Pos() const noexcept {
|
|
|
|
return position;
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position PosRoundUp() const noexcept {
|
|
|
|
return position;
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
std::regex_constants::match_flag_type MatchFlags(const Document *doc, Sci::Position startPos, Sci::Position endPos, Sci::Position lineStartPos, Sci::Position lineEndPos) {
|
2015-06-07 21:19:26 +00:00
|
|
|
std::regex_constants::match_flag_type flagsMatch = std::regex_constants::match_default;
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
if (startPos != lineStartPos) {
|
|
|
|
#ifdef _LIBCPP_VERSION
|
2015-06-07 21:19:26 +00:00
|
|
|
flagsMatch |= std::regex_constants::match_not_bol;
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
if (!doc->IsWordStartAt(startPos)) {
|
|
|
|
flagsMatch |= std::regex_constants::match_not_bow;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
flagsMatch |= std::regex_constants::match_prev_avail;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
if (endPos != lineEndPos) {
|
2015-06-07 21:19:26 +00:00
|
|
|
flagsMatch |= std::regex_constants::match_not_eol;
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
if (!doc->IsWordEndAt(endPos)) {
|
|
|
|
flagsMatch |= std::regex_constants::match_not_eow;
|
|
|
|
}
|
|
|
|
}
|
2015-06-07 21:19:26 +00:00
|
|
|
return flagsMatch;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Iterator, typename Regex>
|
|
|
|
bool MatchOnLines(const Document *doc, const Regex ®exp, const RESearchRange &resr, RESearch &search) {
|
|
|
|
std::match_results<Iterator> match;
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
// MSVC and libc++ have problems with ^ and $ matching line ends inside a range.
|
|
|
|
// CRLF line ends are also a problem as ^ and $ only treat LF as a line end.
|
|
|
|
// The std::regex::multiline option was added to C++17 to improve behaviour but
|
|
|
|
// has not been implemented by compiler runtimes with MSVC always in multiline
|
|
|
|
// mode and libc++ and libstdc++ always in single-line mode.
|
|
|
|
// If multiline regex worked well then the line by line iteration could be removed
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
// for the forwards case and replaced with the following:
|
2019-05-04 18:14:48 +00:00
|
|
|
#ifdef REGEX_MULTILINE
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
const Sci::Position lineStartPos = doc->LineStart(resr.lineRangeStart);
|
|
|
|
const Sci::Position lineEndPos = doc->LineEnd(resr.lineRangeEnd);
|
2019-05-04 18:14:48 +00:00
|
|
|
Iterator itStart(doc, resr.startPos);
|
|
|
|
Iterator itEnd(doc, resr.endPos);
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
const std::regex_constants::match_flag_type flagsMatch = MatchFlags(doc, resr.startPos, resr.endPos, lineStartPos, lineEndPos);
|
2019-05-04 18:14:48 +00:00
|
|
|
const bool matched = std::regex_search(itStart, itEnd, match, regexp, flagsMatch);
|
|
|
|
#else
|
2015-06-07 21:19:26 +00:00
|
|
|
// Line by line.
|
2019-05-04 18:14:48 +00:00
|
|
|
bool matched = false;
|
|
|
|
for (Sci::Line line = resr.lineRangeStart; line != resr.lineRangeBreak; line += resr.increment) {
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
const Sci::Position lineStartPos = doc->LineStart(line);
|
|
|
|
const Sci::Position lineEndPos = doc->LineEnd(line);
|
|
|
|
const Range lineRange = resr.LineRange(line, lineStartPos, lineEndPos);
|
2015-06-07 21:19:26 +00:00
|
|
|
Iterator itStart(doc, lineRange.start);
|
|
|
|
Iterator itEnd(doc, lineRange.end);
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
const std::regex_constants::match_flag_type flagsMatch = MatchFlags(doc, lineRange.start, lineRange.end, lineStartPos, lineEndPos);
|
|
|
|
std::regex_iterator<Iterator> it(itStart, itEnd, regexp, flagsMatch);
|
|
|
|
for (const std::regex_iterator<Iterator> last; it != last; ++it) {
|
|
|
|
match = *it;
|
|
|
|
matched = true;
|
|
|
|
if (resr.increment > 0) {
|
|
|
|
break;
|
2015-06-07 21:19:26 +00:00
|
|
|
}
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
}
|
|
|
|
if (matched) {
|
2015-06-07 21:19:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
#endif
|
2015-06-07 21:19:26 +00:00
|
|
|
if (matched) {
|
2022-01-04 23:07:50 +00:00
|
|
|
for (size_t co = 0; co < match.size() && co < RESearch::MAXTAG; co++) {
|
2015-06-07 21:19:26 +00:00
|
|
|
search.bopat[co] = match[co].first.Pos();
|
|
|
|
search.eopat[co] = match[co].second.PosRoundUp();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return matched;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position Cxx11RegexFindText(const Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s,
|
|
|
|
bool caseSensitive, Sci::Position *length, RESearch &search) {
|
2015-06-07 21:19:26 +00:00
|
|
|
const RESearchRange resr(doc, minPos, maxPos);
|
|
|
|
try {
|
2019-05-04 18:14:48 +00:00
|
|
|
//ElapsedPeriod ep;
|
2015-06-07 21:19:26 +00:00
|
|
|
std::regex::flag_type flagsRe = std::regex::ECMAScript;
|
2021-02-21 04:53:09 +00:00
|
|
|
// Flags that appear to have no effect:
|
2015-06-07 21:19:26 +00:00
|
|
|
// | std::regex::collate | std::regex::extended;
|
|
|
|
if (!caseSensitive)
|
|
|
|
flagsRe = flagsRe | std::regex::icase;
|
|
|
|
|
2022-08-27 07:35:52 +00:00
|
|
|
#if defined(REGEX_MULTILINE) && !defined(_MSC_VER)
|
|
|
|
flagsRe = flagsRe | std::regex::multiline;
|
|
|
|
#endif
|
|
|
|
|
2015-06-07 21:19:26 +00:00
|
|
|
// Clear the RESearch so can fill in matches
|
|
|
|
search.Clear();
|
|
|
|
|
|
|
|
bool matched = false;
|
2022-01-04 23:07:50 +00:00
|
|
|
if (CpUtf8 == doc->dbcsCodePage) {
|
2019-07-21 13:26:02 +00:00
|
|
|
const std::wstring ws = WStringFromUTF8(s);
|
2015-06-07 21:19:26 +00:00
|
|
|
std::wregex regexp;
|
2019-07-21 13:26:02 +00:00
|
|
|
regexp.assign(ws, flagsRe);
|
2015-06-07 21:19:26 +00:00
|
|
|
matched = MatchOnLines<UTF8Iterator>(doc, regexp, resr, search);
|
|
|
|
} else {
|
|
|
|
std::regex regexp;
|
|
|
|
regexp.assign(s, flagsRe);
|
|
|
|
matched = MatchOnLines<ByteIterator>(doc, regexp, resr, search);
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position posMatch = -1;
|
2015-06-07 21:19:26 +00:00
|
|
|
if (matched) {
|
|
|
|
posMatch = search.bopat[0];
|
|
|
|
*length = search.eopat[0] - search.bopat[0];
|
|
|
|
}
|
|
|
|
// Example - search in doc/ScintillaHistory.html for
|
|
|
|
// [[:upper:]]eta[[:space:]]
|
|
|
|
// On MacBook, normally around 1 second but with locale imbued -> 14 seconds.
|
2019-05-04 18:14:48 +00:00
|
|
|
//const double durSearch = ep.Duration(true);
|
2015-06-07 21:19:26 +00:00
|
|
|
//Platform::DebugPrintf("Search:%9.6g \n", durSearch);
|
|
|
|
return posMatch;
|
|
|
|
} catch (std::regex_error &) {
|
|
|
|
// Failed to create regular expression
|
|
|
|
throw RegexError();
|
|
|
|
} catch (...) {
|
|
|
|
// Failed in some other way
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position BuiltinRegex::FindText(Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s,
|
2022-01-04 23:07:50 +00:00
|
|
|
bool caseSensitive, bool, bool, FindOption flags,
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position *length) {
|
2009-04-25 23:38:15 +00:00
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
#ifndef NO_CXX11_REGEX
|
2022-01-04 23:07:50 +00:00
|
|
|
if (FlagSet(flags, FindOption::Cxx11RegEx)) {
|
2015-06-07 21:19:26 +00:00
|
|
|
return Cxx11RegexFindText(doc, minPos, maxPos, s,
|
|
|
|
caseSensitive, length, search);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
const RESearchRange resr(doc, minPos, maxPos);
|
2009-04-25 23:38:15 +00:00
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
const bool posix = FlagSet(flags, FindOption::Posix);
|
2009-04-25 23:38:15 +00:00
|
|
|
|
|
|
|
const char *errmsg = search.Compile(s, *length, caseSensitive, posix);
|
|
|
|
if (errmsg) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
// Find a variable in a property file: \$(\([A-Za-z0-9_.]+\))
|
|
|
|
// Replace first '.' with '-' in each property file variable reference:
|
|
|
|
// Search: \$(\([A-Za-z0-9_-]+\)\.\([A-Za-z0-9_.]+\))
|
|
|
|
// Replace: $(\1-\2)
|
2019-05-04 18:14:48 +00:00
|
|
|
Sci::Position pos = -1;
|
|
|
|
Sci::Position lenRet = 0;
|
|
|
|
const bool searchforLineStart = s[0] == '^';
|
2015-06-07 21:19:26 +00:00
|
|
|
const char searchEnd = s[*length - 1];
|
|
|
|
const char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0';
|
2019-05-04 18:14:48 +00:00
|
|
|
const bool searchforLineEnd = (searchEnd == '$') && (searchEndPrev != '\\');
|
|
|
|
for (Sci::Line line = resr.lineRangeStart; line != resr.lineRangeBreak; line += resr.increment) {
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
const Sci::Position lineStartPos = doc->LineStart(line);
|
|
|
|
const Sci::Position lineEndPos = doc->LineEnd(line);
|
|
|
|
Sci::Position startOfLine = lineStartPos;
|
|
|
|
Sci::Position endOfLine = lineEndPos;
|
2015-06-07 21:19:26 +00:00
|
|
|
if (resr.increment == 1) {
|
|
|
|
if (line == resr.lineRangeStart) {
|
2019-05-04 18:14:48 +00:00
|
|
|
if ((resr.startPos != startOfLine) && searchforLineStart)
|
2009-04-25 23:38:15 +00:00
|
|
|
continue; // Can't match start of line if start position after start of line
|
2015-06-07 21:19:26 +00:00
|
|
|
startOfLine = resr.startPos;
|
2009-04-25 23:38:15 +00:00
|
|
|
}
|
2015-06-07 21:19:26 +00:00
|
|
|
if (line == resr.lineRangeEnd) {
|
2019-05-04 18:14:48 +00:00
|
|
|
if ((resr.endPos != endOfLine) && searchforLineEnd)
|
2009-04-25 23:38:15 +00:00
|
|
|
continue; // Can't match end of line if end position before end of line
|
2015-06-07 21:19:26 +00:00
|
|
|
endOfLine = resr.endPos;
|
2009-04-25 23:38:15 +00:00
|
|
|
}
|
|
|
|
} else {
|
2015-06-07 21:19:26 +00:00
|
|
|
if (line == resr.lineRangeEnd) {
|
2019-05-04 18:14:48 +00:00
|
|
|
if ((resr.endPos != startOfLine) && searchforLineStart)
|
2009-04-25 23:38:15 +00:00
|
|
|
continue; // Can't match start of line if end position after start of line
|
2015-06-07 21:19:26 +00:00
|
|
|
startOfLine = resr.endPos;
|
2009-04-25 23:38:15 +00:00
|
|
|
}
|
2015-06-07 21:19:26 +00:00
|
|
|
if (line == resr.lineRangeStart) {
|
2019-05-04 18:14:48 +00:00
|
|
|
if ((resr.startPos != endOfLine) && searchforLineEnd)
|
2009-04-25 23:38:15 +00:00
|
|
|
continue; // Can't match end of line if start position before end of line
|
2015-06-07 21:19:26 +00:00
|
|
|
endOfLine = resr.startPos;
|
2009-04-25 23:38:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
const DocumentIndexer di(doc, endOfLine);
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
search.SetLineRange(lineStartPos, lineEndPos);
|
2009-04-25 23:38:15 +00:00
|
|
|
int success = search.Execute(di, startOfLine, endOfLine);
|
|
|
|
if (success) {
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
Sci::Position endPos = search.eopat[0];
|
2011-07-17 22:30:49 +00:00
|
|
|
// There can be only one start of a line, so no need to look for last match in line
|
2019-05-04 18:14:48 +00:00
|
|
|
if ((resr.increment == -1) && !searchforLineStart) {
|
2009-04-25 23:38:15 +00:00
|
|
|
// Check for the last match on this line.
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
while (success && (endPos < endOfLine)) {
|
|
|
|
const RESearch::MatchPositions bopat = search.bopat;
|
|
|
|
const RESearch::MatchPositions eopat = search.eopat;
|
|
|
|
pos = endPos;
|
|
|
|
if (pos == bopat[0]) {
|
|
|
|
// empty match
|
|
|
|
pos = doc->NextPosition(pos, 1);
|
|
|
|
}
|
|
|
|
success = search.Execute(di, pos, endOfLine);
|
2009-04-25 23:38:15 +00:00
|
|
|
if (success) {
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
endPos = search.eopat[0];
|
|
|
|
} else {
|
|
|
|
search.bopat = bopat;
|
|
|
|
search.eopat = eopat;
|
2009-04-25 23:38:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Updated to Scintilla 5.4.1 & Lexilla 5.3.0
Scintilla 5.4.1
https://www.scintilla.org/scintilla541.zip
Released 27 December 2023.
1. Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in a Scintilla instance. This feature is provisonal and may change before being declared stable. For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require changes to client code that uses document pointer APIs DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
2. Ctrl-click on a selection deselects it in multiple selection mode.
3. Add SCI_SELECTIONFROMPOINT for modifying multiple selections.
4. Add SCI_SETMOVEEXTENDSSELECTION and SCI_CHANGESELECTIONMODE to simplify selection mode manipulation.
5. Improve performance of global replace by reducing cache invalidation overhead. [Feature #1502](https://sourceforge.net/p/scintilla/feature-requests/1502/).
6. Fix regular expression search for "\<" matching beginning of search when not beginning of word and for "\>" not matching line end. [Bug #2157](https://sourceforge.net/p/scintilla/bugs/2157/).
7. Fix regular expression search failure when search for "\<" followed by search for "\>". [Bug #2413](https://sourceforge.net/p/scintilla/bugs/2413/).
8. Fix regular expression assertion (^, $, \b. \B) failures when using SCFIND_CXX11REGEX. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
9. Fix regular expression bug in reverse direction where shortened match returned. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
10. Avoid character fragments in regular expression search results. [Bug #2405](https://sourceforge.net/p/scintilla/bugs/2405/).
11. With a document that does not have the SC_DOCUMENTOPTION_TEXT_LARGE option set, allocating more than 2G (calling SCI_ALLOCATE or similar) will now fail with SC_STATUS_FAILURE.
12. Protect SCI_REPLACETARGET, SCI_REPLACETARGETMINIMAL, and SCI_REPLACETARGETRE from application changing target in notification handlers. [Bug #2289](https://sourceforge.net/p/scintilla/bugs/2289/).
Lexilla 5.3.0
https://www.scintilla.org/lexilla530.zip
Released 27 December 2023.
1. Fix calling AddStaticLexerModule by defining as C++ instead of C which matches header. [Bug #2421](https://sourceforge.net/p/scintilla/bugs/2421/).
2. Bash: Fix shift operator << incorrectly recognized as here-doc. [Issue #215](https://github.com/ScintillaOrg/lexilla/issues/215).
3. Bash: Fix termination of '${' with first unquoted '}' instead of nesting. [Issue #216](https://github.com/ScintillaOrg/lexilla/issues/216).
4. HTML: JavaScript double-quoted strings may escape line end with '\'. [Issue #214](https://github.com/ScintillaOrg/lexilla/issues/214).
5. Lua: recognize --- doc comments. Defined by [LDoc](https://github.com/lunarmodules/ldoc). Does not recognize --[[-- doc comments which seem less common.
Close #14375
2023-11-19 17:46:55 +00:00
|
|
|
pos = search.bopat[0];
|
|
|
|
lenRet = endPos - pos;
|
2009-04-25 23:38:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*length = lenRet;
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:14:48 +00:00
|
|
|
const char *BuiltinRegex::SubstituteByPosition(Document *doc, const char *text, Sci::Position *length) {
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.clear();
|
2019-05-04 18:14:48 +00:00
|
|
|
for (Sci::Position j = 0; j < *length; j++) {
|
2009-04-25 23:38:15 +00:00
|
|
|
if (text[j] == '\\') {
|
2023-11-05 17:24:41 +00:00
|
|
|
const char chNext = text[++j];
|
|
|
|
if (chNext >= '0' && chNext <= '9') {
|
|
|
|
const unsigned int patNum = chNext - '0';
|
|
|
|
const Sci::Position startPos = search.bopat[patNum];
|
|
|
|
const Sci::Position len = search.eopat[patNum] - startPos;
|
|
|
|
if (len > 0) { // Will be null if try for a match that did not occur
|
|
|
|
const size_t size = substituted.length();
|
|
|
|
substituted.resize(size + len);
|
|
|
|
doc->GetCharRange(substituted.data() + size, startPos, len);
|
|
|
|
}
|
2009-04-25 23:38:15 +00:00
|
|
|
} else {
|
2023-11-05 17:24:41 +00:00
|
|
|
switch (chNext) {
|
2009-04-25 23:38:15 +00:00
|
|
|
case 'a':
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back('\a');
|
2009-04-25 23:38:15 +00:00
|
|
|
break;
|
|
|
|
case 'b':
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back('\b');
|
2009-04-25 23:38:15 +00:00
|
|
|
break;
|
|
|
|
case 'f':
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back('\f');
|
2009-04-25 23:38:15 +00:00
|
|
|
break;
|
|
|
|
case 'n':
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back('\n');
|
2009-04-25 23:38:15 +00:00
|
|
|
break;
|
|
|
|
case 'r':
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back('\r');
|
2009-04-25 23:38:15 +00:00
|
|
|
break;
|
|
|
|
case 't':
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back('\t');
|
2009-04-25 23:38:15 +00:00
|
|
|
break;
|
|
|
|
case 'v':
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back('\v');
|
2009-04-25 23:38:15 +00:00
|
|
|
break;
|
2010-07-12 22:19:51 +00:00
|
|
|
case '\\':
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back('\\');
|
2010-07-12 22:19:51 +00:00
|
|
|
break;
|
2009-04-25 23:38:15 +00:00
|
|
|
default:
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back('\\');
|
2009-04-25 23:38:15 +00:00
|
|
|
j--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2013-08-28 00:44:27 +00:00
|
|
|
substituted.push_back(text[j]);
|
2009-04-25 23:38:15 +00:00
|
|
|
}
|
|
|
|
}
|
2019-05-04 18:14:48 +00:00
|
|
|
*length = substituted.length();
|
2013-08-28 00:44:27 +00:00
|
|
|
return substituted.c_str();
|
2009-04-25 23:38:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef SCI_OWNREGEX
|
|
|
|
|
2022-01-04 23:07:50 +00:00
|
|
|
RegexSearchBase *Scintilla::Internal::CreateRegexSearch(CharClassify *charClassTable) {
|
2009-06-24 19:09:31 +00:00
|
|
|
return new BuiltinRegex(charClassTable);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|