Update to Scintilla 5.3.3 and Lexilla 5.2.2

update to https://www.scintilla.org/scintilla533.zip with:

   1. Released 8 February 2023.
   2. Fix SCI_LINESJOIN bug where carriage returns were incorrectly retained. Bug #2372.
   3. Fix SCI_VERTICALCENTRECARET to update the vertical scroll position.
   4. When an autocompletion list is shown in response to SCN_CHARADDED, do not process character as fill-up or stop. This avoids closing immediately when a character may both trigger and finish autocompletion.
   5. On Cocoa fix character input bug where dotless 'i' and some other extended Latin characters could not be entered. The change also stops SCI_ASSIGNCMDKEY from working with these characters on Cocoa. Bug #2374.
   6. On GTK, support IME context. Feature #1476.
   7. On GTK on Win32, fix scrolling speed to not be too fast. Bug #2375.
   8. On Qt, fix indicator drawing past left of text pane over margin. Bug #2373, Bug #1956.
   9. On Qt, allow scrolling with mouse wheel when scroll bar hidden.

and https://www.scintilla.org/lexilla522.zip with

   1. Released 8 February 2023.
   2. C++: Fix keywords that start with non-ASCII. Also affects other lexers. Issue #130.
   3. Matlab: Include more prefix and suffix characters in numeric literals. Issue #120.
   4. Matlab: More accurate treatment of line ends inside strings. Matlab and Octave are different here. Issue #18.
   5. Modula-3: Don't treat identifier suffix that matches keyword as keyword. Issue #129.
   6. Modula-3: Fix endless loop in folder. Issue #128.
   7. Modula-3: Fix access to lines beyond document end in folder. Issue #131.
   8. Python: Don't highlight match and case as keywords in contexts where they probably aren't used as keywords. Pull request #122.
   9. X12: Support empty envelopes. Bug #2369.

update CMakeLists.txt to latest changes within vcxproj file

Close #13082
This commit is contained in:
Christian Grasser 2023-02-09 17:57:24 +01:00 committed by Don Ho
parent 9eab1f566d
commit 43182e1d04
105 changed files with 2087 additions and 867 deletions

View File

@ -385,13 +385,13 @@ IF (WIN32)
if ( MSVC )
#do not use for mingw builds
SET(CMAKE_CXX_FLAGS "/EHa /MP /W4")
SET(defs -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0600 -D_USE_64BIT_TIME_T -DTIXML_USE_STL -DTIXMLA_USE_STL -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NON_CONFORMING_SWPRINTFS )
SET(defs -DUNICODE -D_UNICODE -D_WIN32_WINNT=_WIN32_WINNT_VISTA -D_USE_64BIT_TIME_T -DTIXML_USE_STL -DTIXMLA_USE_STL -DNOMINMAX -DOEMRESOURCE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING )
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
else ( MSVC )
# For possible MinGW compilation
SET(CMAKE_CXX_FLAGS "-include../gcc/gcc-fixes.h -std=c++20 -fpermissive -municode")
SET(defs -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0600 -D_USE_64BIT_TIME_T -DTIXML_USE_STL -DTIXMLA_USE_STL )
SET(defs -DUNICODE -D_UNICODE -D_WIN32_WINNT=_WIN32_WINNT_VISTA -D_USE_64BIT_TIME_T -DTIXML_USE_STL -DTIXMLA_USE_STL -DNOMINMAX -DOEMRESOURCE)
endif ( MSVC )
ENDIF (WIN32)

View File

@ -36,6 +36,7 @@
**.jl text
**.json text
**.lua text
**.m3 text
**.matlab text
**.ml text
**.nim text

View File

@ -15,7 +15,7 @@
#include <vector>
#include <set>
#if !_WIN32
#if !defined(_WIN32)
#include <dlfcn.h>
#else
#include <windows.h>
@ -29,7 +29,7 @@
namespace {
#if _WIN32
#if defined(_WIN32)
typedef FARPROC Function;
typedef HMODULE Module;
constexpr const char *pathSeparator = "\\";
@ -49,7 +49,7 @@ T FunctionPointer(Function function) noexcept {
return fp;
}
#if _WIN32
#if defined(_WIN32)
std::wstring WideStringFromUTF8(std::string_view sv) {
const int sLength = static_cast<int>(sv.length());
@ -85,7 +85,7 @@ std::vector<std::string> lexers;
std::vector<std::string> libraryProperties;
Function FindSymbol(Module m, const char *symbol) noexcept {
#if _WIN32
#if defined(_WIN32)
return ::GetProcAddress(m, symbol);
#else
return dlsym(m, symbol);
@ -149,7 +149,7 @@ bool Lexilla::Load(std::string_view sharedLibraryPaths) {
// No '.' in name so add extension
path.append(LEXILLA_EXTENSION);
}
#if _WIN32
#if defined(_WIN32)
// Convert from UTF-8 to wide characters
std::wstring wsPath = WideStringFromUTF8(path);
Module lexillaDL = ::LoadLibraryW(wsPath.c_str());
@ -246,7 +246,7 @@ Scintilla::ILexer5 *Lexilla::MakeLexer(std::string_view languageName) {
if (pCreateLexerDefault) {
return pCreateLexerDefault(sLanguageName.c_str());
}
#ifdef LEXILLA_STATIC
#if defined(LEXILLA_STATIC)
Scintilla::ILexer5 *pLexer = CreateLexer(sLanguageName.c_str());
if (pLexer) {
return pLexer;

View File

@ -55,9 +55,10 @@ constParameter:lexilla/lexers/LexHex.cxx
knownConditionTrueFalse:lexilla/lexers/LexHex.cxx
constParameter:lexilla/lexers/LexHTML.cxx
variableScope:lexilla/lexers/LexInno.cxx
variableScope:lexilla/lexers/LexJulia.cxx
constParameter:lexilla/lexers/LexJulia.cxx
knownConditionTrueFalse:lexilla/lexers/LexJulia.cxx
unreadVariable:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexLaTeX.cxx
constParameter:lexilla/lexers/LexLaTeX.cxx
constParameter:lexilla/lexers/LexLisp.cxx
@ -151,6 +152,9 @@ constVariable:lexilla/lexers/LexTACL.cxx
constVariable:lexilla/lexers/LexTADS3.cxx
constVariable:lexilla/lexers/LexTAL.cxx
// cppcheck appears wrong as atKeyPath must be remembered between loops
variableScope:lexilla/lexers/LexRegistry.cxx
// Suppress everything in test example files
*:lexilla/test/examples/*
@ -159,3 +163,6 @@ constVariable:lexilla/lexers/LexTAL.cxx
// cppcheck gives up inside catch.hpp
*:lexilla/test/unit/UnitTester.cxx
*:lexilla/test/unit/unitTest.cxx
// cppcheck fails REQUIRE from Catch
comparisonOfFuncReturningBoolError:lexilla/test/unit/*.cxx

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20221206" />
<meta name="Date.Modified" content="20230208" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
.logo {
@ -61,8 +61,8 @@
<font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3">Release version 5.2.1<br />
Site last modified December 6 2022</font>
<font color="#FFCC99" size="3">Release version 5.2.2<br />
Site last modified February 8 2023</font>
</td>
<td width="20%">
&nbsp;
@ -77,13 +77,13 @@
</tr>
</table>
<ul id="versionlist">
<li>Version 5.2.2 improves C++, Matlab, Modula-3, Python, and X12.</li>
<li>Version 5.2.1 improves Batch, F#, Markdown, and PowerShell.</li>
<li>Version 5.2.0 improves PowerShell and R.</li>
<li>Version 5.1.9 improves Julia and Properties.</li>
<li>Version 5.1.8 improves F#, MS SQL, PowerShell, and Visual Prolog.</li>
<li>Version 5.1.7 improves CMake, HTML, Matlab, Raku, Ruby, and VHDL.</li>
<li>Version 5.1.6 improves Markdown and Ruby.</li>
<li>Version 5.1.5 improves Bash, Batch, F#, HTML, Inno Setup, and Python.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

View File

@ -26,9 +26,9 @@
<table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
<tr>
<td>
<font size="4"> <a href="https://www.scintilla.org/lexilla521.zip">
<font size="4"> <a href="https://www.scintilla.org/lexilla522.zip">
Windows</a>&nbsp;&nbsp;
<a href="https://www.scintilla.org/lexilla521.tgz">
<a href="https://www.scintilla.org/lexilla522.tgz">
GTK/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -42,7 +42,7 @@
containing very few restrictions.
</p>
<h3>
Release 5.2.1
Release 5.2.2
</h3>
<h4>
Source Code
@ -50,8 +50,8 @@
The source code package contains all of the source code for Lexilla but no binary
executable code and is available in
<ul>
<li><a href="https://www.scintilla.org/lexilla521.zip">zip format</a> (1.2M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/lexilla521.tgz">tgz format</a> (0.9M) commonly used on Linux and compatible operating systems</li>
<li><a href="https://www.scintilla.org/lexilla522.zip">zip format</a> (1.2M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/lexilla522.tgz">tgz format</a> (0.9M) commonly used on Linux and compatible operating systems</li>
</ul>
Instructions for building on both Windows and Linux are included in the readme file.
<h4>

View File

@ -585,6 +585,46 @@
</tr>
</table>
<h2>Releases</h2>
<h3>
<a href="https://www.scintilla.org/lexilla522.zip">Release 5.2.2</a>
</h3>
<ul>
<li>
Released 8 February 2023.
</li>
<li>
C++: Fix keywords that start with non-ASCII. Also affects other lexers.
<a href="https://github.com/ScintillaOrg/lexilla/issues/130">Issue #130</a>.
</li>
<li>
Matlab: Include more prefix and suffix characters in numeric literals.
<a href="https://github.com/ScintillaOrg/lexilla/issues/120">Issue #120</a>.
</li>
<li>
Matlab: More accurate treatment of line ends inside strings. Matlab and Octave are different here.
<a href="https://github.com/ScintillaOrg/lexilla/issues/18">Issue #18</a>.
</li>
<li>
Modula-3: Don't treat identifier suffix that matches keyword as keyword.
<a href="https://github.com/ScintillaOrg/lexilla/issues/129">Issue #129</a>.
</li>
<li>
Modula-3: Fix endless loop in folder.
<a href="https://github.com/ScintillaOrg/lexilla/issues/128">Issue #128</a>.
</li>
<li>
Modula-3: Fix access to lines beyond document end in folder.
<a href="https://github.com/ScintillaOrg/lexilla/issues/131">Issue #131</a>.
</li>
<li>
Python: Don't highlight match and case as keywords in contexts where they probably aren't used as keywords.
<a href="https://github.com/ScintillaOrg/lexilla/pull/122">Pull request #122</a>.
</li>
<li>
X12: Support empty envelopes.
<a href="https://sourceforge.net/p/scintilla/bugs/2369/">Bug #2369</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/lexilla521.zip">Release 5.2.1</a>
</h3>

View File

@ -39,23 +39,23 @@ GCC or Clang or as C++.
#include <stdio.h>
#if _WIN32
#if defined(_WIN32)
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#ifdef __cplusplus
#if defined(__cplusplus)
#include "ILexer.h"
#endif
#include "Lexilla.h"
#ifdef __cplusplus
#if defined(__cplusplus)
using namespace Lexilla;
#endif
#if _WIN32
#if defined(_WIN32)
typedef FARPROC Function;
typedef HMODULE Module;
#else
@ -64,7 +64,7 @@ typedef void *Module;
#endif
static Function FindSymbol(Module m, const char *symbol) {
#if _WIN32
#if defined(_WIN32)
return GetProcAddress(m, symbol);
#else
return dlsym(m, symbol);
@ -77,7 +77,7 @@ int main(int argc, char *argv[]) {
if (argc > 1) {
libPath = argv[1];
}
#if _WIN32
#if defined(_WIN32)
Module lexillaLibrary = LoadLibraryA(libPath);
#else
Module lexillaLibrary = dlopen(libPath, RTLD_LAZY);

View File

@ -79,7 +79,7 @@ public:
}
};
#if _WIN32
#if defined(_WIN32)
#define EXPORT_FUNCTION __declspec(dllexport)
#define CALLING_CONVENTION __stdcall
#else

View File

@ -10,7 +10,7 @@
#define LEXILLA_H
// Define the default Lexilla shared library name for each platform
#if _WIN32
#if defined(_WIN32)
#define LEXILLA_LIB "lexilla"
#define LEXILLA_EXTENSION ".dll"
#else
@ -23,7 +23,7 @@
#endif
// On Win32 use the stdcall calling convention otherwise use the standard calling convention
#if _WIN32
#if defined(_WIN32)
#define LEXILLA_CALL __stdcall
#else
#define LEXILLA_CALL
@ -41,7 +41,7 @@
#define DEPRECATE_DEFINITION
#endif
#ifdef __cplusplus
#if defined(__cplusplus)
// Must have already included ILexer.h to have Scintilla::ILexer5 defined.
using Scintilla::ILexer5;
#else
@ -50,7 +50,7 @@ typedef void ILexer5;
typedef ILexer5 *(*LexerFactoryFunction)();
#ifdef __cplusplus
#if defined(__cplusplus)
namespace Lexilla {
#endif
@ -63,7 +63,7 @@ typedef const char *(LEXILLA_CALL *GetLibraryPropertyNamesFn)();
typedef void(LEXILLA_CALL *SetLibraryPropertyFn)(const char *key, const char *value);
typedef const char *(LEXILLA_CALL *GetNameSpaceFn)();
#ifdef __cplusplus
#if defined(__cplusplus)
}
#endif
@ -80,7 +80,7 @@ typedef const char *(LEXILLA_CALL *GetNameSpaceFn)();
// Static linking prototypes
#ifdef __cplusplus
#if defined(__cplusplus)
extern "C" {
#endif
@ -93,11 +93,11 @@ const char * LEXILLA_CALL GetLibraryPropertyNames();
void LEXILLA_CALL SetLibraryProperty(const char *key, const char *value);
const char *LEXILLA_CALL GetNameSpace();
#ifdef __cplusplus
#if defined(__cplusplus)
}
#endif
#ifdef __cplusplus
#if defined(__cplusplus)
namespace Lexilla {
class LexerModule;
}

View File

@ -104,6 +104,13 @@ static bool followsKeyword(StyleContext &sc, Accessor &styler) {
return styler.StyleAt(pos) == SCE_COFFEESCRIPT_WORD;
}
#if defined(__clang__)
#if __has_warning("-Wunused-but-set-variable")
// Disable warning for visibleChars
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#endif
#endif
static void ColouriseCoffeeScriptDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
Accessor &styler) {

View File

@ -255,7 +255,7 @@ void SCI_METHOD LexerDMIS::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i
scCTX.GetCurrent(tmpStr, (MAX_STR_LEN-1));
// The following strncpy is copying from a string back onto itself which is weird and causes warnings
// but is harmless so turn off the warning
#if defined(__GNUC__) && !defined(__APPLE__)
#if defined(__GNUC__) && !defined(__clang__)
// Disable warning for strncpy
#pragma GCC diagnostic ignored "-Wrestrict"
#endif

View File

@ -286,7 +286,11 @@ static void ColouriseMatlabOctaveDoc(
} else if (sc.state == SCE_MATLAB_NUMBER) {
if (!isdigit(sc.ch) && sc.ch != '.'
&& !(sc.ch == 'e' || sc.ch == 'E')
&& !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
&& !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))
&& !(((sc.ch == 'x' || sc.ch == 'X') && sc.chPrev == '0') || (sc.ch >= 'a' && sc.ch <= 'f') || (sc.ch >= 'A' && sc.ch <= 'F'))
&& !(sc.ch == 's' || sc.ch == 'S' || sc.ch == 'u' || sc.ch == 'U')
&& !(sc.ch == 'i' || sc.ch == 'I' || sc.ch == 'j' || sc.ch == 'J')
&& !(sc.ch == '_')) {
sc.SetState(SCE_MATLAB_DEFAULT);
transpose = true;
}
@ -297,14 +301,16 @@ static void ColouriseMatlabOctaveDoc(
} else {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
}
} else if (sc.MatchLineEnd()) {
sc.SetState(SCE_MATLAB_DEFAULT);
}
} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
if (sc.ch == '\\' && !ismatlab) {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
sc.Forward(); // skip escape sequence, new line and others after backlash
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
} else if (sc.MatchLineEnd()) {
sc.SetState(SCE_MATLAB_DEFAULT);
}
} else if (sc.state == SCE_MATLAB_COMMAND) {
if (sc.atLineEnd) {

View File

@ -83,7 +83,7 @@ static inline unsigned IsOperator( StyleContext & sc, WordList & op ) {
static inline bool IsEOL( Accessor &styler, Sci_PositionU curPos ) {
unsigned ch = styler.SafeGetCharAt( curPos );
if( ( ch == '\r' && styler.SafeGetCharAt( curPos + 1 ) == '\n' ) ||
( ch == '\n' ) ) {
( ch == '\n' && styler.SafeGetCharAt( curPos - 1 ) != '\r' ) ) {
return true;
}
return false;
@ -261,7 +261,7 @@ static void FoldModulaDoc( Sci_PositionU startPos,
if( clv_new < clv_old ) {
nextLevel--;
pos = styler.LineStart( cln );
while( ( ch = styler.SafeGetCharAt( pos ) ) != '\n' ) {
while( ( ch = styler.SafeGetCharAt( pos, '\n' )) != '\n') {
if( ch == 'P' ) {
if( styler.StyleAt(pos) == SCE_MODULA_KEYWORD ) {
if( checkKeyIdentOper( styler, pos, endPos,
@ -386,6 +386,8 @@ static void ColouriseModulaDoc( Sci_PositionU startPos,
continue;
} else {
/** check procedure identifier */
sc.Forward( kl );
continue;
}
} else {
for( i = 0; i < BUFLEN - 1; i++ ) {

View File

@ -221,6 +221,13 @@ Sci_Position SCI_METHOD LexerABL::WordListSet(int n, const char *wl) {
return firstModification;
}
#if defined(__clang__)
#if __has_warning("-Wunused-but-set-variable")
// Disable warning for visibleChars
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#endif
#endif
void SCI_METHOD LexerABL::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
LexAccessor styler(pAccess);

View File

@ -218,6 +218,54 @@ bool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) {
return true;
}
unsigned char GetNextNonWhitespaceChar(Accessor &styler, Sci_PositionU pos, Sci_PositionU maxPos, Sci_PositionU *charPosPtr = nullptr) {
while (pos < maxPos) {
const unsigned char ch = styler.SafeGetCharAt(pos, '\0');
if (!(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) {
if (charPosPtr != nullptr) {
*charPosPtr = pos;
}
return ch;
}
pos++;
}
return '\0';
}
// Returns whether symbol is "match" or "case" and it is an identifier &
// not a keyword. Does not require the line to end with : so "match\n"
// and "match (x)\n" return false because match could be a keyword once
// more text is added
bool IsMatchOrCaseIdentifier(const StyleContext &sc, Accessor &styler, const char *symbol) {
if (strcmp(symbol, "match") != 0 && strcmp(symbol, "case") != 0) {
return false;
}
if (!IsFirstNonWhitespace(sc.currentPos - strlen(symbol), styler)) {
return true;
}
// The match keyword can be followed by an expression; the case keyword
// is a bit more restrictive but not much. Here, we look for the next
// char and return false if the char cannot start an expression; for '.'
// we look at the following char to see if it's a digit because .1 is a
// number
Sci_PositionU nextCharPos = 0;
const unsigned char nextChar = GetNextNonWhitespaceChar(styler, sc.currentPos, sc.lineEnd, &nextCharPos);
if (nextChar == '=' || nextChar == '#') {
return true;
}
if (nextChar == '.' && nextCharPos >= sc.currentPos) {
const unsigned char followingChar = GetNextNonWhitespaceChar(styler, nextCharPos+1, sc.lineEnd);
if (!IsADigit(followingChar)) {
return true;
}
}
return false;
}
// Options used for LexerPython
struct OptionsPython {
int whingeLevel;
@ -613,7 +661,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
int style = SCE_P_IDENTIFIER;
if ((kwLast == kwImport) && (strcmp(s, "as") == 0)) {
style = SCE_P_WORD;
} else if (keywords.InList(s)) {
} else if (keywords.InList(s) && !IsMatchOrCaseIdentifier(sc, styler, s)) {
style = SCE_P_WORD;
} else if (kwLast == kwClass) {
style = SCE_P_CLASSNAME;

View File

@ -466,6 +466,13 @@ void SCI_METHOD LexerVisualProlog::Lex(Sci_PositionU startPos, Sci_Position leng
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
#if defined(__clang__)
#if __has_warning("-Wunused-but-set-variable")
// Disable warning for visibleChars
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#endif
#endif
void SCI_METHOD LexerVisualProlog::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
LexAccessor styler(pAccess);

View File

@ -232,16 +232,16 @@ LexerX12::Terminator LexerX12::InitialiseFromISA(IDocument *pAccess)
pAccess->GetCharRange(&m_SeparatorElement, 3, 1);
pAccess->GetCharRange(&m_SeparatorSubElement, 104, 1);
// Look for GS, as that's the next segment. Anything between 105 and GS is our segment separator.
Sci_Position posGS;
char bufGS[3] = { 0 };
for (posGS = 105; posGS < length - 2; posGS++)
// Look for GS, as that's the next segment. Anything between 105 and GS/IEA is our segment separator.
Sci_Position posNextSegment;
char bufSegment[3] = { 0 };
for (posNextSegment = 105; posNextSegment < length - 3; posNextSegment++)
{
pAccess->GetCharRange(bufGS, posGS, 2);
if (bufGS[0] == 'G' && bufGS[1] == 'S')
pAccess->GetCharRange(bufSegment, posNextSegment, 3);
if (!memcmp (bufSegment, "GS", 2) || !memcmp(bufSegment, "IEA", 3))
{
m_SeparatorSegment.resize(posGS - 105);
pAccess->GetCharRange(&m_SeparatorSegment.at(0), 105, posGS - 105);
m_SeparatorSegment.resize(posNextSegment - 105);
pAccess->GetCharRange(&m_SeparatorSegment.at(0), 105, posNextSegment - 105);
// Is some of that CR+LF?
size_t nPos = m_SeparatorSegment.find_last_not_of("\r\n");

View File

@ -95,8 +95,9 @@ public:
return buf[position - startPos];
}
bool IsLeadByte(char ch) const {
const unsigned char uch = ch;
return
(static_cast<unsigned char>(ch) >= 0x80) && // non-ASCII
(uch >= 0x80) && // non-ASCII
(encodingType == EncodingType::dbcs) && // IsDBCSLeadByte only for DBCS
pAccess->IsDBCSLeadByte(ch);
}
@ -125,16 +126,19 @@ public:
return pAccess->StyleAt(position);
}
int StyleIndexAt(Sci_Position position) const {
return static_cast<unsigned char>(pAccess->StyleAt(position));
const unsigned char style = pAccess->StyleAt(position);
return style;
}
// Return style value from buffer when in buffer, else retrieve from document.
// This is faster and can avoid calls to Flush() as that may be expensive.
int BufferStyleAt(Sci_Position position) const {
const Sci_Position index = position - startPosStyling;
if (index >= 0 && index < validLen) {
return static_cast<unsigned char>(styleBuf[index]);
const unsigned char style = styleBuf[index];
return style;
}
return static_cast<unsigned char>(pAccess->StyleAt(position));
const unsigned char style = pAccess->StyleAt(position);
return style;
}
Sci_Position GetLine(Sci_Position position) const {
return pAccess->LineFromPosition(position);
@ -148,7 +152,7 @@ public:
int LevelAt(Sci_Position line) const {
return pAccess->GetLevel(line);
}
Sci_Position Length() const {
Sci_Position Length() const noexcept {
return lenDoc;
}
void Flush() {
@ -169,10 +173,10 @@ public:
pAccess->StartStyling(start);
startPosStyling = start;
}
Sci_PositionU GetStartSegment() const {
Sci_PositionU GetStartSegment() const noexcept {
return startSeg;
}
void StartSegment(Sci_PositionU pos) {
void StartSegment(Sci_PositionU pos) noexcept {
startSeg = pos;
}
void ColourTo(Sci_PositionU pos, int chAttr) {
@ -185,7 +189,7 @@ public:
if (validLen + (pos - startSeg + 1) >= bufferSize)
Flush();
const char attr = static_cast<char>(chAttr);
const unsigned char attr = chAttr & 0xffU;
if (validLen + (pos - startSeg + 1) >= bufferSize) {
// Too big for buffer so send directly
pAccess->SetStyleFor(pos - startSeg + 1, attr);

View File

@ -72,7 +72,7 @@ constexpr int Maximum(int a, int b) noexcept {
}
// Shut up annoying Visual C++ warnings:
#ifdef _MSC_VER
#if defined(_MSC_VER)
#pragma warning(disable: 4244 4456 4457)
#endif

View File

@ -30,14 +30,16 @@ class StyleContext {
if (multiByteAccess) {
chNext = multiByteAccess->GetCharacterAndWidth(currentPos+width, &widthNext);
} else {
chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+width, 0));
const unsigned char charNext = styler.SafeGetCharAt(currentPos + width, 0);
chNext = charNext;
}
// End of line determined from line end position, allowing CR, LF,
// CRLF and Unicode line ends as set by document.
const Sci_Position currentPosSigned = currentPos;
if (currentLine < lineDocEnd)
atLineEnd = static_cast<Sci_Position>(currentPos) >= (lineStartNext-1);
atLineEnd = currentPosSigned >= (lineStartNext-1);
else // Last line
atLineEnd = static_cast<Sci_Position>(currentPos) >= lineStartNext;
atLineEnd = currentPosSigned >= lineStartNext;
}
public:
@ -115,11 +117,12 @@ public:
styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
state = state_;
}
Sci_Position LengthCurrent() const {
Sci_Position LengthCurrent() const noexcept {
return currentPos - styler.GetStartSegment();
}
int GetRelative(Sci_Position n, char chDefault='\0') {
return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n, chDefault));
const unsigned char chRelative = styler.SafeGetCharAt(currentPos + n, chDefault);
return chRelative;
}
int GetRelativeCharacter(Sci_Position n) {
if (n == 0)
@ -140,25 +143,32 @@ public:
return chReturn;
} else {
// fast version for single byte encodings
return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos + n, 0));
const unsigned char chRelative = styler.SafeGetCharAt(currentPos + n, 0);
return chRelative;
}
}
bool MatchLineEnd() const noexcept {
return static_cast<Sci_Position>(currentPos) == lineEnd;
const Sci_Position currentPosSigned = currentPos;
return currentPosSigned == lineEnd;
}
bool Match(char ch0) const {
return ch == static_cast<unsigned char>(ch0);
bool Match(char ch0) const noexcept {
const unsigned char uch0 = ch0;
return ch == uch0;
}
bool Match(char ch0, char ch1) const {
return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1));
bool Match(char ch0, char ch1) const noexcept {
const unsigned char uch0 = ch0;
const unsigned char uch1 = ch1;
return (ch == uch0) && (chNext == uch1);
}
bool Match(const char *s) {
if (ch != static_cast<unsigned char>(*s))
const unsigned char su = *s;
if (ch != su)
return false;
s++;
if (!*s)
return true;
if (chNext != static_cast<unsigned char>(*s))
const unsigned char sNext = *s;
if (chNext != sNext)
return false;
s++;
for (int n=2; *s; n++) {

View File

@ -147,10 +147,11 @@ bool WordList::Set(const char *s) {
bool WordList::InList(const char *s) const noexcept {
if (!words)
return false;
const unsigned char firstChar = s[0];
const char first = s[0];
const unsigned char firstChar = first;
int j = starts[firstChar];
if (j >= 0) {
while (words[j][0] == firstChar) {
while (words[j][0] == first) {
if (s[1] == words[j][1]) {
const char *a = words[j] + 1;
const char *b = s + 1;
@ -189,10 +190,11 @@ bool WordList::InList(const char *s) const noexcept {
bool WordList::InListAbbreviated(const char *s, const char marker) const noexcept {
if (!words)
return false;
const unsigned char firstChar = s[0];
const char first = s[0];
const unsigned char firstChar = first;
int j = starts[firstChar];
if (j >= 0) {
while (words[j][0] == firstChar) {
while (words[j][0] == first) {
bool isSubword = false;
int start = 1;
if (words[j][1] == marker) {
@ -243,10 +245,11 @@ bool WordList::InListAbbreviated(const char *s, const char marker) const noexcep
bool WordList::InListAbridged(const char *s, const char marker) const noexcept {
if (!words)
return false;
const unsigned char firstChar = s[0];
const char first = s[0];
const unsigned char firstChar = first;
int j = starts[firstChar];
if (j >= 0) {
while (words[j][0] == firstChar) {
while (words[j][0] == first) {
const char *a = words[j];
const char *b = s;
while (*a && *a == *b) {

View File

@ -11,7 +11,7 @@
#include <vector>
#include <initializer_list>
#if _WIN32
#if defined(_WIN32)
#define EXPORT_FUNCTION __declspec(dllexport)
#define CALLING_CONVENTION __stdcall
#else

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>5.2.1</string>
<string>5.2.2</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>

View File

@ -851,7 +851,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.2.1;
CURRENT_PROJECT_VERSION = 5.2.2;
DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
@ -877,7 +877,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.2.1;
CURRENT_PROJECT_VERSION = 5.2.2;
DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;

View File

@ -4,8 +4,8 @@
#include <windows.h>
#define VERSION_LEXILLA "5.2.1"
#define VERSION_WORDS 5, 2, 1, 0
#define VERSION_LEXILLA "5.2.2"
#define VERSION_WORDS 5, 2, 2, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_WORDS

View File

@ -125,7 +125,7 @@ void TestDocument::Set(std::string_view sv) {
lineLevels.resize(lineStarts.size(), 0x400);
}
#if _MSC_VER
#if defined(_MSC_VER)
// IDocument interface does not specify noexcept so best to not add it to implementation
#pragma warning(disable: 26440)
#endif

View File

@ -963,7 +963,7 @@ int main() {
const std::filesystem::path baseDirectory = FindLexillaDirectory(std::filesystem::current_path());
if (!baseDirectory.empty()) {
const std::filesystem::path examplesDirectory = baseDirectory / "test" / "examples";
#ifdef LEXILLA_STATIC
#if defined(LEXILLA_STATIC)
success = AccessLexilla(examplesDirectory);
#else
const std::filesystem::path sharedLibrary = baseDirectory / "bin" / LEXILLA_LIB;

View File

@ -0,0 +1,13 @@
rem remark and comment bug
findstr /c:"rem this" "file"
findstr /c:":: this" "file"
:: SingleQuoted command string
for /f %%A in ('rem this') do echo %%A
:: DoubleQuoted string
for /f %%A in ("rem this") do echo %%A
:: BackQuote command string
for /f "usebackq" %%A in (`rem this`) do echo %%A

View File

@ -0,0 +1,14 @@
0 400 0 rem remark and comment bug
0 400 0
0 400 0 findstr /c:"rem this" "file"
0 400 0 findstr /c:":: this" "file"
0 400 0
0 400 0 :: SingleQuoted command string
0 400 0 for /f %%A in ('rem this') do echo %%A
0 400 0
0 400 0 :: DoubleQuoted string
0 400 0 for /f %%A in ("rem this") do echo %%A
0 400 0
0 400 0 :: BackQuote command string
0 400 0 for /f "usebackq" %%A in (`rem this`) do echo %%A
0 400 0

View File

@ -0,0 +1,13 @@
{1}rem remark and comment bug
{0}
{5}findstr{0} /c:"rem this" "file"
{5}findstr{0} /c:":: this" "file"
{1}:: SingleQuoted command string
{2}for{0} /f {6}%%A{2} in{0} ('rem this'){2} do echo{0} {6}%%A{0}
{1}:: DoubleQuoted string
{2}for{0} /f {6}%%A{2} in{0} ("rem this"){2} do echo{0} {6}%%A{0}
{1}:: BackQuote command string
{2}for{0} /f "usebackq" {6}%%A{2} in{0} (`rem this`){2} do echo{0} {6}%%A{0}

View File

@ -0,0 +1,9 @@
// coding: utf-8
// All three following symbols should highlight as keywords
cheese
käse
сыр
// Lookalikes with ASCII so should not highlight:
сыp
cыp

View File

@ -0,0 +1,10 @@
0 400 400 // coding: utf-8
0 400 400 // All three following symbols should highlight as keywords
0 400 400 cheese
0 400 400 käse
0 400 400 сыр
1 400 400
0 400 400 // Lookalikes with ASCII so should not highlight:
0 400 400 сыp
0 400 400 cыp
1 400 400

View File

@ -0,0 +1,9 @@
{2}// coding: utf-8
// All three following symbols should highlight as keywords
{5}cheese{0}
{5}käse{0}
{5}сыр{0}
{2}// Lookalikes with ASCII so should not highlight:
{11}сыp{0}
{11}cыp{0}

View File

@ -1,3 +1,4 @@
# coding: utf-8
lexer.*.cxx=cpp
keywords.*.cxx=int let uuid
keywords2.*.cxx=second
@ -17,3 +18,6 @@ fold=1
fold.preprocessor=1
fold.comment=1
fold.compact=1
match 130NonAsciiKeyword.cxx
keywords.*.cxx=cheese käse сыр

View File

@ -0,0 +1,85 @@
namespace Literals
module Issue110 =
let hexA = +0xA1B2C3D4
let hexB = -0xCC100000
// regression checks
let hexC = 0xCC100000
let binA = +0b0000_1010
let binB = -0b1010_0000
let binC = 0b1010_0000
let octA = +0o1237777700
let octB = -0o1237777700
let octC = 0o1237777700
let i8a = +0001y
let i8b = -0001y
let u8 = 0001uy
let f32a = +0.001e-003
let f32b = -0.001E+003
let f32c = 0.001e-003
let f128a = +0.001m
let f128b = -0.001m
let f128c = 0.001m
// invalid literals
let hexD = 0xa0bcde0o
let hexE = +0xa0bcd0o
let hexF = -0xa0bcd0o
let binD = 0b1010_1110xf000
let binE = +0b1010_1110xf000
let binF = -0b1010_1110xf000
let binG = 0b1010_1110o
let binH = +0b1010_1110o
let binI = -0b1010_1110o
let octD = 0o3330xaBcDeF
let octE = +0o3330xaBcDe
let octF = -0o3330xaBcDe
let octG = 0o3330b
let octH = 0o3330b
let octI = 0o3330b
module Issue111 =
// invalid literals
let a = 0000_123abc
let b = +000_123abc
let c = -0001_23abc
let d = 00123_000b
let e = +0123_000o
let f = -0123_000xcd
module Issue112 =
let i64 = 0001L
let u64 = 001UL
let f32a = 001.F
let f32b = +01.0F
let f32c = -01.00000F
let f32d = 0b0000_0010lf
let f32e = 0o000_010lf
let f32f = 0x0000000000000010lf
let f64a = 0b0000_0010LF
let f64b = 0o000_010LF
let f64c = 0x0000000000000010LF
let f128a = 001.M
let f128b = +01.0M
let f128c = -01.00000M
// regression checks
let i32 = -0001l
let u32 = +001ul
let i128 = 9999999999999999999999999999I
let f32g = 001.f
let f32h = +01.0f
let f32i = -01.00000f
let f64d = 010000e+009
let f64e = +001.0e-009
let f64f = -001.e+009
let f128d = 001.m
let f128e = +01.0m
let f128f = -01.00000m
// arithmetic expressions
let a = -001.f+01.0F
let b = +0b0111_111UL-0x100UL
let c = -01.0F + +001.f
let d = -0x100UL - +0b0111_111UL

View File

@ -0,0 +1,86 @@
0 400 400 namespace Literals
1 400 400
0 400 400 module Issue110 =
0 400 400 let hexA = +0xA1B2C3D4
0 400 400 let hexB = -0xCC100000
1 400 400
0 400 400 // regression checks
0 400 400 let hexC = 0xCC100000
0 400 400 let binA = +0b0000_1010
0 400 400 let binB = -0b1010_0000
0 400 400 let binC = 0b1010_0000
0 400 400 let octA = +0o1237777700
0 400 400 let octB = -0o1237777700
0 400 400 let octC = 0o1237777700
0 400 400 let i8a = +0001y
0 400 400 let i8b = -0001y
0 400 400 let u8 = 0001uy
0 400 400 let f32a = +0.001e-003
0 400 400 let f32b = -0.001E+003
0 400 400 let f32c = 0.001e-003
0 400 400 let f128a = +0.001m
0 400 400 let f128b = -0.001m
0 400 400 let f128c = 0.001m
1 400 400
0 400 400 // invalid literals
0 400 400 let hexD = 0xa0bcde0o
0 400 400 let hexE = +0xa0bcd0o
0 400 400 let hexF = -0xa0bcd0o
0 400 400 let binD = 0b1010_1110xf000
0 400 400 let binE = +0b1010_1110xf000
0 400 400 let binF = -0b1010_1110xf000
0 400 400 let binG = 0b1010_1110o
0 400 400 let binH = +0b1010_1110o
0 400 400 let binI = -0b1010_1110o
0 400 400 let octD = 0o3330xaBcDeF
0 400 400 let octE = +0o3330xaBcDe
0 400 400 let octF = -0o3330xaBcDe
0 400 400 let octG = 0o3330b
0 400 400 let octH = 0o3330b
0 400 400 let octI = 0o3330b
1 400 400
0 400 400 module Issue111 =
0 400 400 // invalid literals
0 400 400 let a = 0000_123abc
0 400 400 let b = +000_123abc
0 400 400 let c = -0001_23abc
0 400 400 let d = 00123_000b
0 400 400 let e = +0123_000o
0 400 400 let f = -0123_000xcd
1 400 400
0 400 400 module Issue112 =
0 400 400 let i64 = 0001L
0 400 400 let u64 = 001UL
0 400 400 let f32a = 001.F
0 400 400 let f32b = +01.0F
0 400 400 let f32c = -01.00000F
0 400 400 let f32d = 0b0000_0010lf
0 400 400 let f32e = 0o000_010lf
0 400 400 let f32f = 0x0000000000000010lf
0 400 400 let f64a = 0b0000_0010LF
0 400 400 let f64b = 0o000_010LF
0 400 400 let f64c = 0x0000000000000010LF
0 400 400 let f128a = 001.M
0 400 400 let f128b = +01.0M
0 400 400 let f128c = -01.00000M
1 400 400
0 400 400 // regression checks
0 400 400 let i32 = -0001l
0 400 400 let u32 = +001ul
0 400 400 let i128 = 9999999999999999999999999999I
0 400 400 let f32g = 001.f
0 400 400 let f32h = +01.0f
0 400 400 let f32i = -01.00000f
0 400 400 let f64d = 010000e+009
0 400 400 let f64e = +001.0e-009
0 400 400 let f64f = -001.e+009
0 400 400 let f128d = 001.m
0 400 400 let f128e = +01.0m
0 400 400 let f128f = -01.00000m
1 400 400
0 400 400 // arithmetic expressions
0 400 400 let a = -001.f+01.0F
0 400 400 let b = +0b0111_111UL-0x100UL
0 400 400 let c = -01.0F + +001.f
0 400 400 let d = -0x100UL - +0b0111_111UL
1 400 400

View File

@ -0,0 +1,85 @@
{1}namespace{0} {6}Literals{0}
{1}module{0} {6}Issue110{0} {12}={0}
{1}let{0} {6}hexA{0} {12}={0} {13}+0xA1B2C3D4{0}
{1}let{0} {6}hexB{0} {12}={0} {13}-0xCC100000{0}
{9}// regression checks{0}
{1}let{0} {6}hexC{0} {12}={0} {13}0xCC100000{0}
{1}let{0} {6}binA{0} {12}={0} {13}+0b0000_1010{0}
{1}let{0} {6}binB{0} {12}={0} {13}-0b1010_0000{0}
{1}let{0} {6}binC{0} {12}={0} {13}0b1010_0000{0}
{1}let{0} {6}octA{0} {12}={0} {13}+0o1237777700{0}
{1}let{0} {6}octB{0} {12}={0} {13}-0o1237777700{0}
{1}let{0} {6}octC{0} {12}={0} {13}0o1237777700{0}
{1}let{0} {6}i8a{0} {12}={0} {13}+0001y{0}
{1}let{0} {6}i8b{0} {12}={0} {13}-0001y{0}
{1}let{0} {6}u8{0} {12}={0} {13}0001uy{0}
{1}let{0} {6}f32a{0} {12}={0} {13}+0.001e-003{0}
{1}let{0} {6}f32b{0} {12}={0} {13}-0.001E+003{0}
{1}let{0} {6}f32c{0} {12}={0} {13}0.001e-003{0}
{1}let{0} {6}f128a{0} {12}={0} {13}+0.001m{0}
{1}let{0} {6}f128b{0} {12}={0} {13}-0.001m{0}
{1}let{0} {6}f128c{0} {12}={0} {13}0.001m{0}
{9}// invalid literals{0}
{1}let{0} {6}hexD{0} {12}={0} {13}0xa0bcde0{0}o
{1}let{0} {6}hexE{0} {12}={0} {13}+0xa0bcd0{0}o
{1}let{0} {6}hexF{0} {12}={0} {13}-0xa0bcd0{0}o
{1}let{0} {6}binD{0} {12}={0} {13}0b1010_1110{0}x{6}f000{0}
{1}let{0} {6}binE{0} {12}={0} {13}+0b1010_1110{0}x{6}f000{0}
{1}let{0} {6}binF{0} {12}={0} {13}-0b1010_1110{0}x{6}f000{0}
{1}let{0} {6}binG{0} {12}={0} {13}0b1010_1110{0}o
{1}let{0} {6}binH{0} {12}={0} {13}+0b1010_1110{0}o
{1}let{0} {6}binI{0} {12}={0} {13}-0b1010_1110{0}o
{1}let{0} {6}octD{0} {12}={0} {13}0o3330{0}x{6}aBcDeF{0}
{1}let{0} {6}octE{0} {12}={0} {13}+0o3330{0}x{6}aBcDe{0}
{1}let{0} {6}octF{0} {12}={0} {13}-0o3330{0}x{6}aBcDe{0}
{1}let{0} {6}octG{0} {12}={0} {13}0o3330{0}b
{1}let{0} {6}octH{0} {12}={0} {13}0o3330{0}b
{1}let{0} {6}octI{0} {12}={0} {13}0o3330{0}b
{1}module{0} {6}Issue111{0} {12}={0}
{9}// invalid literals{0}
{1}let{0} {6}a{0} {12}={0} {13}0000_123{0}a{6}bc{0}
{1}let{0} {6}b{0} {12}={0} {13}+000_123{0}a{6}bc{0}
{1}let{0} {6}c{0} {12}={0} {13}-0001_23{0}a{6}bc{0}
{1}let{0} {6}d{0} {12}={0} {13}00123_000{0}b
{1}let{0} {6}e{0} {12}={0} {13}+0123_000{0}o
{1}let{0} {6}f{0} {12}={0} {13}-0123_000{0}x{6}cd{0}
{1}module{0} {6}Issue112{0} {12}={0}
{1}let{0} {6}i64{0} {12}={0} {13}0001L{0}
{1}let{0} {6}u64{0} {12}={0} {13}001UL{0}
{1}let{0} {6}f32a{0} {12}={0} {13}001.F{0}
{1}let{0} {6}f32b{0} {12}={0} {13}+01.0F{0}
{1}let{0} {6}f32c{0} {12}={0} {13}-01.00000F{0}
{1}let{0} {6}f32d{0} {12}={0} {13}0b0000_0010lf{0}
{1}let{0} {6}f32e{0} {12}={0} {13}0o000_010lf{0}
{1}let{0} {6}f32f{0} {12}={0} {13}0x0000000000000010lf{0}
{1}let{0} {6}f64a{0} {12}={0} {13}0b0000_0010LF{0}
{1}let{0} {6}f64b{0} {12}={0} {13}0o000_010LF{0}
{1}let{0} {6}f64c{0} {12}={0} {13}0x0000000000000010LF{0}
{1}let{0} {6}f128a{0} {12}={0} {13}001.M{0}
{1}let{0} {6}f128b{0} {12}={0} {13}+01.0M{0}
{1}let{0} {6}f128c{0} {12}={0} {13}-01.00000M{0}
{9}// regression checks{0}
{1}let{0} {6}i32{0} {12}={0} {13}-0001l{0}
{1}let{0} {6}u32{0} {12}={0} {13}+001ul{0}
{1}let{0} {6}i128{0} {12}={0} {13}9999999999999999999999999999I{0}
{1}let{0} {6}f32g{0} {12}={0} {13}001.f{0}
{1}let{0} {6}f32h{0} {12}={0} {13}+01.0f{0}
{1}let{0} {6}f32i{0} {12}={0} {13}-01.00000f{0}
{1}let{0} {6}f64d{0} {12}={0} {13}010000e+009{0}
{1}let{0} {6}f64e{0} {12}={0} {13}+001.0e-009{0}
{1}let{0} {6}f64f{0} {12}={0} {13}-001.e+009{0}
{1}let{0} {6}f128d{0} {12}={0} {13}001.m{0}
{1}let{0} {6}f128e{0} {12}={0} {13}+01.0m{0}
{1}let{0} {6}f128f{0} {12}={0} {13}-01.00000m{0}
{9}// arithmetic expressions{0}
{1}let{0} {6}a{0} {12}={0} {13}-001.f{12}+{13}01.0F{0}
{1}let{0} {6}b{0} {12}={0} {13}+0b0111_111UL{12}-{13}0x100UL{0}
{1}let{0} {6}c{0} {12}={0} {13}-01.0F{0} {12}+{0} {13}+001.f{0}
{1}let{0} {6}d{0} {12}={0} {13}-0x100UL{0} {12}-{0} {13}+0b0111_111UL{0}

View File

@ -0,0 +1,12 @@
The number:
338269006135764734700913562171
is prime. Therefore:
1. the only factors of 338269006135764734700913562171 are:
1
338269006135764734700913562171
2. 338269006135764734700913562171 is a natural number

View File

@ -0,0 +1,13 @@
0 400 0 The number:
0 400 0
0 400 0 338269006135764734700913562171
0 400 0
0 400 0 is prime. Therefore:
0 400 0
0 400 0 1. the only factors of 338269006135764734700913562171 are:
0 400 0
0 400 0 1
0 400 0 338269006135764734700913562171
0 400 0
0 400 0 2. 338269006135764734700913562171 is a natural number
0 400 0

View File

@ -0,0 +1,12 @@
{0}The number:{1}
{0}338269006135764734700913562171{1}
{0}is prime. Therefore:{1}
{12} {14}1.{0} the only factors of 338269006135764734700913562171 are:{1}
{12} {0} 1{1}
{12} {0} 338269006135764734700913562171{1}
{12} {14}2.{0} 338269006135764734700913562171 is a natural number{1}

View File

@ -13,4 +13,9 @@ h=123;
% Octave terminates string at 3rd ", Matlab at 4th
i="\" "; % " %
% Matlab (unlike Octave) does not allow string continuation with an escape
b = "multi\
line"
% end

View File

@ -13,5 +13,10 @@
1 400 400
0 400 400 % Octave terminates string at 3rd ", Matlab at 4th
0 400 400 i="\" "; % " %
1 400 400
0 400 400 % Matlab (unlike Octave) does not allow string continuation with an escape
0 400 400 b = "multi\
0 400 400 line"
1 400 400
0 400 400 % end
1 400 400

View File

@ -5,12 +5,17 @@
{7}e{6}={8}"\"{6};{0}
{7}f{6}={3}3{6};{0}
{1}%" this should be a comment (colored as such), instead it closes the string{0}
{7}g{6}={8}"
h=123;
%"{0} {7}this{0} {7}is{0} {7}a{0} {7}syntax{0} {7}error{0} {7}in{0} {7}Matlab{0} {6}({7}about{0} {5}'g'{6}),{0}
{7}g{6}={8}"{0}
{7}h{6}={3}123{6};{0}
{1}%" this is a syntax error in Matlab (about 'g'),{0}
{1}% followed by a valid assignment (of 'h'){0}
{1}% Instead, 'h' is colored as part of the string{0}
{1}% Octave terminates string at 3rd ", Matlab at 4th{0}
{7}i{6}={8}"\"{0} {8}"; % "{0} {1}%{0}
{1}% Matlab (unlike Octave) does not allow string continuation with an escape{0}
{7}b{0} {6}={0} {8}"multi\{0}
{7}line{8}"{0}
{1}% end{0}

View File

@ -1,4 +1,14 @@
% Ensure escape sequences still work in octave
% Octave terminates string at 3rd ", Matlab at 4th
i="\" "; % " %
% Octave allows string continuation with an escape
b = "multi\
line"
% No escape so string ends at line end
c = "multi
line"
% end

View File

@ -1,5 +1,15 @@
0 400 400 % Ensure escape sequences still work in octave
0 400 400 % Octave terminates string at 3rd ", Matlab at 4th
0 400 400 i="\" "; % " %
1 400 400
1 400 400
0 400 400 % Octave allows string continuation with an escape
0 400 400 b = "multi\
0 400 400 line"
1 400 400
0 400 400 % No escape so string ends at line end
0 400 400 c = "multi
0 400 400 line"
1 400 400
0 400 400 % end
1 400 400

View File

@ -1,4 +1,14 @@
{1}% Ensure escape sequences still work in octave{0}
{1}% Octave terminates string at 3rd ", Matlab at 4th{0}
{7}i{6}={8}"\" "{6};{0} {1}% " %{0}
{1}% Octave allows string continuation with an escape{0}
{7}b{0} {6}={0} {8}"multi\
line"{0}
{1}% No escape so string ends at line end {0}
{7}c{0} {6}={0} {8}"multi{0}
{7}line{8}"{0}
{1}% end{0}

View File

@ -0,0 +1,28 @@
d = 123;
x = 0x123ABC;
b = 0b010101;
xs64 = 0x2As64;
xs32 = 0x2As32;
xs16 = 0x2As16;
xs8 = 0x2As8;
xu64 = 0x2Au64;
xu32 = 0x2Au32;
xu16 = 0x2Au16;
xu8 = 0x2Au8;
bs64 = 0b10s64;
bs32 = 0b10s32;
bs16 = 0b10s16;
bs8 = 0b10s8;
bu64 = 0b10u64;
bu32 = 0b10u32;
bu16 = 0b10u16;
bu8 = 0b10u8;
c = .1;
c = 1.1;
c = .1e1;
c = 1.1e1;
c = 1e1;
c = 1i;
c = 1j;
c = .1e2j;
c = 1e2j;

View File

@ -0,0 +1,29 @@
0 400 400 d = 123;
0 400 400 x = 0x123ABC;
0 400 400 b = 0b010101;
0 400 400 xs64 = 0x2As64;
0 400 400 xs32 = 0x2As32;
0 400 400 xs16 = 0x2As16;
0 400 400 xs8 = 0x2As8;
0 400 400 xu64 = 0x2Au64;
0 400 400 xu32 = 0x2Au32;
0 400 400 xu16 = 0x2Au16;
0 400 400 xu8 = 0x2Au8;
0 400 400 bs64 = 0b10s64;
0 400 400 bs32 = 0b10s32;
0 400 400 bs16 = 0b10s16;
0 400 400 bs8 = 0b10s8;
0 400 400 bu64 = 0b10u64;
0 400 400 bu32 = 0b10u32;
0 400 400 bu16 = 0b10u16;
0 400 400 bu8 = 0b10u8;
0 400 400 c = .1;
0 400 400 c = 1.1;
0 400 400 c = .1e1;
0 400 400 c = 1.1e1;
0 400 400 c = 1e1;
0 400 400 c = 1i;
0 400 400 c = 1j;
0 400 400 c = .1e2j;
0 400 400 c = 1e2j;
1 400 400

View File

@ -0,0 +1,28 @@
{7}d{0} {6}={0} {3}123{6};{0}
{7}x{0} {6}={0} {3}0x123ABC{6};{0}
{7}b{0} {6}={0} {3}0b010101{6};{0}
{7}xs64{0} {6}={0} {3}0x2As64{6};{0}
{7}xs32{0} {6}={0} {3}0x2As32{6};{0}
{7}xs16{0} {6}={0} {3}0x2As16{6};{0}
{7}xs8{0} {6}={0} {3}0x2As8{6};{0}
{7}xu64{0} {6}={0} {3}0x2Au64{6};{0}
{7}xu32{0} {6}={0} {3}0x2Au32{6};{0}
{7}xu16{0} {6}={0} {3}0x2Au16{6};{0}
{7}xu8{0} {6}={0} {3}0x2Au8{6};{0}
{7}bs64{0} {6}={0} {3}0b10s64{6};{0}
{7}bs32{0} {6}={0} {3}0b10s32{6};{0}
{7}bs16{0} {6}={0} {3}0b10s16{6};{0}
{7}bs8{0} {6}={0} {3}0b10s8{6};{0}
{7}bu64{0} {6}={0} {3}0b10u64{6};{0}
{7}bu32{0} {6}={0} {3}0b10u32{6};{0}
{7}bu16{0} {6}={0} {3}0b10u16{6};{0}
{7}bu8{0} {6}={0} {3}0b10u8{6};{0}
{7}c{0} {6}={0} {3}.1{6};{0}
{7}c{0} {6}={0} {3}1.1{6};{0}
{7}c{0} {6}={0} {3}.1e1{6};{0}
{7}c{0} {6}={0} {3}1.1e1{6};{0}
{7}c{0} {6}={0} {3}1e1{6};{0}
{7}c{0} {6}={0} {3}1i{6};{0}
{7}c{0} {6}={0} {3}1j{6};{0}
{7}c{0} {6}={0} {3}.1e2j{6};{0}
{7}c{0} {6}={0} {3}1e2j{6};{0}

View File

@ -0,0 +1,15 @@
(* This file caused an infinite loop in the folder before #128 was fixed.*)
MODULE Form;
IMPORT
PROCEDURE (bf: ButtonForm) InitializeComponent(), NEW;
BEGIN
bf.SuspendLayout();
REGISTER(bf.button1.Click, bf.button1_Click);
bf.get_Controls().Add(bf.button2);
END InitializeComponent;
BEGIN
NEW(bf);
Wfm.Application.Run(bf);
END Form.

View File

@ -0,0 +1,16 @@
0 400 400 (* This file caused an infinite loop in the folder before #128 was fixed.*)
0 400 400 MODULE Form;
0 400 400 IMPORT
1 400 400
0 400 400 PROCEDURE (bf: ButtonForm) InitializeComponent(), NEW;
2 400 401 + BEGIN
0 401 401 | bf.SuspendLayout();
0 401 401 | REGISTER(bf.button1.Click, bf.button1_Click);
0 401 401 | bf.get_Controls().Add(bf.button2);
0 401 400 | END InitializeComponent;
1 400 400
2 400 401 + BEGIN
0 401 401 | NEW(bf);
0 401 401 | Wfm.Application.Run(bf);
0 401 400 | END Form.
1 400 400

View File

@ -0,0 +1,15 @@
{1}(* This file caused an infinite loop in the folder before #128 was fixed.*){0}
{4}MODULE{0} Form{16};{0}
{4}IMPORT{0}
{4}PROCEDURE{0} {16}({0}bf{16}:{0} ButtonForm{16}){0} InitializeComponent{16}(),{0} {5}NEW{16};{0}
{4}BEGIN{0}
bf{16}.{0}SuspendLayout{16}();{0}
REGISTER{16}({0}bf{16}.{0}button1{16}.{0}Click{16},{0} bf{16}.{0}button1_Click{16});{0}
bf{16}.{0}get_Controls{16}().{0}Add{16}({0}bf{16}.{0}button2{16});{0}
{4}END{0} InitializeComponent{16};{0}
{4}BEGIN{0}
{5}NEW{16}({0}bf{16});{0}
Wfm{16}.{0}Application{16}.{0}Run{16}({0}bf{16});{0}
{4}END{0} Form{16}.{0}

View File

@ -0,0 +1,8 @@
INTERFACE Test;
TYPE
(* Opaque types *)
HANDLE = ADDRESS;
HMOD(* Module handle *) = HANDLE;
END Test.

View File

@ -0,0 +1,9 @@
0 400 400 INTERFACE Test;
1 400 400
0 400 400 TYPE
0 400 400 (* Opaque types *)
0 400 400 HANDLE = ADDRESS;
0 400 400 HMOD(* Module handle *) = HANDLE;
1 400 400
0 400 3ff END Test.
1 3ff 3ff

View File

@ -0,0 +1,8 @@
{4}INTERFACE{0} Test{16};{0}
{4}TYPE{0}
{1}(* Opaque types *){0}
HANDLE {16}={0} {5}ADDRESS{16};{0}
HMOD{1}(* Module handle *){0} {16}={0} HANDLE{16};{0}
{4}END{0} Test{16}.{0}

View File

@ -0,0 +1,26 @@
lexer.*.m3=modula
# Keywords
keywords.*.m3=AND ANY ARRAY AS BEGIN BITS BRANDED BY CASE CONST\
DIV DO ELSE ELSIF END EVAL EXCEPT EXCEPTION EXIT EXPORTS FINALLY FOR FROM\
GENERIC IF IMPORT IN INTERFACE LOCK LOOP METHODS MOD MODULE NOT OBJECT OF\
OR OVERRIDES PROCEDURE RAISE RAISES READONLY RECORD REF REPEAT RETURN\
REVEAL ROOT SET THEN TO TRY TYPE TYPECASE UNSAFE UNTIL UNTRACED VALUE VAR\
WHILE WITH
# Reserved identifiers
keywords2.*.m3=ABS ADDRESS ADR ADRSIZE BITSIZE BOOLEAN BYTESIZE\
CARDINAL CEILING CHAR DEC DISPOSE EXTENDED FALSE FIRST FLOAT FLOOR INC\
INTEGER ISTYPE LAST LONGINT LONGREAL LOOPHOLE MAX MIN MUTEX NARROW NEW NIL\
NULL NUMBER ORD REAL REFANY ROUND SUBARRAY TEXT TRUE TRUNC TYPECODE VAL\
WIDECHAR
# Operators
keywords3.*.m3= + < # = ; .. : - > { } | := <: * <= ( ) ^ , =>\
/ >= [ ] . &
# Pragmas keywords
keywords4.*.m3= EXTERNAL INLINE ASSERT TRACE FATAL UNUSED\
OBSOLETE NOWARN LINE PRAGMA
# Escape sequences
keywords5.*.m3= f n r t \ " '
# Doxygene keywords
keywords6.*.m3= author authors file brief date proc param result
fold=1

View File

@ -0,0 +1,35 @@
# Treat any leading [-+] as default to reduce match complexity
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_numeric_literals?view=powershell-7.3#examples
100
100u
100D
100l
100uL
100us
100uy
100y
1e2
1.e2
0x1e2
0x1e2L
0x1e2D
482D
482gb
482ngb
0x1e2lgb
0b1011011
0xFFFFs
0xFFFFFFFF
-0xFFFFFFFF
0xFFFFFFFFu
# Float
0.5
.5
# Range
1..100
# Issue118: 7d is numeric while 7z is user defined keyword
7d
7z

View File

@ -0,0 +1,36 @@
0 400 400 # Treat any leading [-+] as default to reduce match complexity
0 400 400 # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_numeric_literals?view=powershell-7.3#examples
0 400 400 100
0 400 400 100u
0 400 400 100D
0 400 400 100l
0 400 400 100uL
0 400 400 100us
0 400 400 100uy
0 400 400 100y
0 400 400 1e2
0 400 400 1.e2
0 400 400 0x1e2
0 400 400 0x1e2L
0 400 400 0x1e2D
0 400 400 482D
0 400 400 482gb
0 400 400 482ngb
0 400 400 0x1e2lgb
0 400 400 0b1011011
0 400 400 0xFFFFs
0 400 400 0xFFFFFFFF
0 400 400 -0xFFFFFFFF
0 400 400 0xFFFFFFFFu
1 400 400
0 400 400 # Float
0 400 400 0.5
0 400 400 .5
1 400 400
0 400 400 # Range
0 400 400 1..100
1 400 400
0 400 400 # Issue118: 7d is numeric while 7z is user defined keyword
0 400 400 7d
0 400 400 7z
0 400 0

View File

@ -0,0 +1,35 @@
{1}# Treat any leading [-+] as default to reduce match complexity{0}
{1}# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_numeric_literals?view=powershell-7.3#examples{0}
{4}100{0}
{4}100u{0}
{4}100D{0}
{4}100l{0}
{4}100uL{0}
{4}100us{0}
{4}100uy{0}
{4}100y{0}
{4}1e2{0}
{4}1.e2{0}
{4}0x1e2{0}
{4}0x1e2L{0}
{4}0x1e2D{0}
{4}482D{0}
{4}482gb{0}
{4}482ngb{0}
{4}0x1e2lgb{0}
{4}0b1011011{0}
{4}0xFFFFs{0}
{4}0xFFFFFFFF{0}
{6}-{4}0xFFFFFFFF{0}
{4}0xFFFFFFFFu{0}
{1}# Float{0}
{4}0.5{0}
{4}.5{0}
{1}# Range{0}
{4}1{6}..{4}100{0}
{1}# Issue118: 7d is numeric while 7z is user defined keyword{0}
{4}7d{0}
{12}7z{0}

View File

@ -1,5 +1,5 @@
lexer.*.py=python
keywords.*.py=class def else for if import in pass print return while with yield
keywords.*.py=case class def else for if import in match pass print return while with yield
keywords2.*.py=hilight
fold=1
fold.compact=1

View File

@ -0,0 +1,25 @@
# Match and case as keywords
match (x):
case +1:
pass
case -1:
pass
case []:
pass
# Match and case as identifiers
match = 1
def match():
pass
match.group()
1 + match
case.attribute
# Unfortunately wrong classifications; should be rare in real code because
# non-call expressions usually don't begin lines, the exceptions are match(x)
# and case(x)
match(x)
case(x)
match + 1
case + 1
case[1]

View File

@ -0,0 +1,26 @@
0 400 0 # Match and case as keywords
2 400 0 + match (x):
2 404 0 + case +1:
0 408 0 | pass
2 404 0 + case -1:
0 408 0 | pass
2 404 0 + case []:
0 408 0 | pass
1 408 0 |
0 400 0 # Match and case as identifiers
0 400 0 match = 1
2 400 0 + def match():
0 404 0 | pass
0 400 0 match.group()
0 400 0 1 + match
0 400 0 case.attribute
1 400 0
0 400 0 # Unfortunately wrong classifications; should be rare in real code because
0 400 0 # non-call expressions usually don't begin lines, the exceptions are match(x)
0 400 0 # and case(x)
0 400 0 match(x)
0 400 0 case(x)
0 400 0 match + 1
0 400 0 case + 1
0 400 0 case[1]
1 400 0

View File

@ -0,0 +1,25 @@
{1}# Match and case as keywords{0}
{5}match{0} {10}({11}x{10}):{0}
{5}case{0} {10}+{2}1{10}:{0}
{5}pass{0}
{5}case{0} {10}-{2}1{10}:{0}
{5}pass{0}
{5}case{0} {10}[]:{0}
{5}pass{0}
{1}# Match and case as identifiers{0}
{11}match{0} {10}={0} {2}1{0}
{5}def{0} {9}match{10}():{0}
{5}pass{0}
{11}match{10}.{11}group{10}(){0}
{2}1{0} {10}+{0} {11}match{0}
{11}case{10}.{11}attribute{0}
{1}# Unfortunately wrong classifications; should be rare in real code because{0}
{1}# non-call expressions usually don't begin lines, the exceptions are match(x){0}
{1}# and case(x){0}
{5}match{10}({11}x{10}){0}
{5}case{10}({11}x{10}){0}
{5}match{0} {10}+{0} {2}1{0}
{5}case{0} {10}+{0} {2}1{0}
{5}case{10}[{2}1{10}]{0}

View File

@ -0,0 +1,2 @@
ISA*00* *00* *01*0011223456 *01*999999999 *950120*0147*U*00300*000000007*0*P*~
IEA*2*000000007

View File

@ -0,0 +1,3 @@
2 400 0 + ISA*00* *00* *01*0011223456 *01*999999999 *950120*0147*U*00300*000000007*0*P*~
0 401 0 | IEA*2*000000007
0 400 0

View File

@ -0,0 +1,2 @@
{2}ISA{7}*{0}00{7}*{0} {7}*{0}00{7}*{0} {7}*{0}01{7}*{0}0011223456 {7}*{0}01{7}*{0}999999999 {7}*{0}950120{7}*{0}0147{7}*{0}U{7}*{0}00300{7}*{0}000000007{7}*{0}0{7}*{0}P{7}*{8}~{6}
{2}IEA{7}*{0}2{7}*{0}000000007{6}

View File

@ -28,6 +28,17 @@ TEST_CASE("WordList") {
REQUIRE(!wl.InList("class"));
}
SECTION("InListUnicode") {
// "cheese" in English
// "kase" ('k', 'a with diaeresis', 's', 'e') in German
// "syr", ('CYRILLIC SMALL LETTER ES', 'CYRILLIC SMALL LETTER YERU', 'CYRILLIC SMALL LETTER ER') in Russian
wl.Set("cheese \x6b\xc3\xa4\x73\x65 \xd1\x81\xd1\x8b\xd1\x80");
REQUIRE(3 == wl.Length());
REQUIRE(wl.InList("cheese"));
REQUIRE(wl.InList("\x6b\xc3\xa4\x73\x65"));
REQUIRE(wl.InList("\xd1\x81\xd1\x8b\xd1\x80"));
}
SECTION("Set") {
// Check whether Set returns whether it has changed correctly
const bool changed = wl.Set("else struct");
@ -49,7 +60,7 @@ TEST_CASE("WordList") {
}
SECTION("InListAbbreviated") {
wl.Set("else stru~ct w~hile");
wl.Set("else stru~ct w~hile \xd1\x81~\xd1\x8b\xd1\x80");
REQUIRE(wl.InListAbbreviated("else", '~'));
REQUIRE(wl.InListAbbreviated("struct", '~'));
@ -62,10 +73,13 @@ TEST_CASE("WordList") {
// TODO: Next line fails but should allow single character prefixes
//REQUIRE(wl.InListAbbreviated("w", '~'));
REQUIRE(!wl.InListAbbreviated("", '~'));
// Russian syr
REQUIRE(wl.InListAbbreviated("\xd1\x81\xd1\x8b\xd1\x80", '~'));
}
SECTION("InListAbridged") {
wl.Set("list w.~.active bo~k a~z ~_frozen");
wl.Set("list w.~.active bo~k a~z ~_frozen \xd1\x81~\xd1\x80");
REQUIRE(wl.InListAbridged("list", '~'));
REQUIRE(wl.InListAbridged("w.front.active", '~'));
@ -85,5 +99,8 @@ TEST_CASE("WordList") {
REQUIRE(wl.InListAbridged("abcz", '~'));
REQUIRE(wl.InListAbridged("abz", '~'));
REQUIRE(wl.InListAbridged("az", '~'));
// Russian syr
REQUIRE(wl.InListAbridged("\xd1\x81\xd1\x8b\xd1\x80", '~'));
}
}

View File

@ -1 +1 @@
521
522

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>5.3.2</string>
<string>5.3.3</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>

View File

@ -573,7 +573,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5.3.2;
CURRENT_PROJECT_VERSION = 5.3.3;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@ -635,7 +635,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5.3.2;
CURRENT_PROJECT_VERSION = 5.3.3;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -665,7 +665,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5.3.2;
CURRENT_PROJECT_VERSION = 5.3.3;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
@ -699,7 +699,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5.3.2;
CURRENT_PROJECT_VERSION = 5.3.3;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;

View File

@ -2228,6 +2228,10 @@ bool ScintillaCocoa::KeyboardInput(NSEvent *event) {
// Handle each entry individually. Usually we only have one entry anyway.
for (size_t i = 0; i < input.length; i++) {
const UniChar originalKey = [input characterAtIndex: i];
// Some Unicode extended Latin characters overlap the Keys enumeration so treat them
// only as and not as command keys.
if (originalKey >= static_cast<UniChar>(Keys::Down) && originalKey <= static_cast<UniChar>(Keys::Menu))
continue;
NSEventModifierFlags modifierFlags = event.modifierFlags;
Keys key = KeyTranslate(originalKey, modifierFlags);

View File

@ -129,7 +129,7 @@
<h1>Scintilla Documentation</h1>
<p>Last edited 15 November 2022 NH</p>
<p>Last edited 14 January 2023 NH</p>
<p style="background:#90F0C0">Scintilla 5 has moved the lexers from Scintilla into a new
<a href="Lexilla.html">Lexilla</a> project.<br />
@ -6891,8 +6891,9 @@ struct Sci_TextToFindFull {
<p><code>SCI_FORMATRANGE</code> can be used to draw the text onto a display surface
which can include a printer display surface. Printed output shows text styling as on the
screen, but it hides all margins except a line number margin. All special marker effects are
removed and the selection and caret are hidden.</p>
screen, but it hides all margins except a line number margin.
Markers do not appear in a margin but will change line background colour.
The selection and caret are hidden.</p>
<p>Different platforms use different display surface ID types to print on. On Windows, these are
<code>HDC</code>s., on GTK 3.x <code>cairo_t *</code>,

View File

@ -26,9 +26,9 @@
<table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
<tr>
<td>
<font size="4"> <a href="https://www.scintilla.org/scintilla532.zip">
<font size="4"> <a href="https://www.scintilla.org/scintilla533.zip">
Windows</a>&nbsp;&nbsp;
<a href="https://www.scintilla.org/scintilla532.tgz">
<a href="https://www.scintilla.org/scintilla533.tgz">
GTK/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -42,7 +42,7 @@
containing very few restrictions.
</p>
<h3>
Release 5.3.2
Release 5.3.3
</h3>
<h4>
Source Code
@ -50,8 +50,8 @@
The source code package contains all of the source code for Scintilla but no binary
executable code and is available in
<ul>
<li><a href="https://www.scintilla.org/scintilla532.zip">zip format</a> (1.4M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/scintilla532.tgz">tgz format</a> (1.2M) commonly used on Linux and compatible operating systems</li>
<li><a href="https://www.scintilla.org/scintilla533.zip">zip format</a> (1.4M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/scintilla533.tgz">tgz format</a> (1.3M) commonly used on Linux and compatible operating systems</li>
</ul>
Instructions for building on both Windows and Linux are included in the readme file.
<h4>

View File

@ -575,9 +575,52 @@
<td>Reinhard Nißl</td>
<td>Ferdinand Oeinck</td>
<td>Michael Heath</td>
<td>Enrico Tröger</td>
</tr>
</table>
<h2>Releases</h2>
<h3>
<a href="https://www.scintilla.org/scintilla533.zip">Release 5.3.3</a>
</h3>
<ul>
<li>
Released 8 February 2023.
</li>
<li>
Fix SCI_LINESJOIN bug where carriage returns were incorrectly retained.
<a href="https://sourceforge.net/p/scintilla/bugs/2372/">Bug #2372</a>.
</li>
<li>
Fix SCI_VERTICALCENTRECARET to update the vertical scroll position.
</li>
<li>
When an autocompletion list is shown in response to SCN_CHARADDED, do not process character as fill-up or stop.
This avoids closing immediately when a character may both trigger and finish autocompletion.
</li>
<li>
On Cocoa fix character input bug where dotless 'i' and some other extended
Latin characters could not be entered.
The change also stops SCI_ASSIGNCMDKEY from working with these characters
on Cocoa.
<a href="https://sourceforge.net/p/scintilla/bugs/2374/">Bug #2374</a>.
</li>
<li>
On GTK, support IME context.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1476/">Feature #1476</a>.
</li>
<li>
On GTK on Win32, fix scrolling speed to not be too fast.
<a href="https://sourceforge.net/p/scintilla/bugs/2375/">Bug #2375</a>.
</li>
<li>
On Qt, fix indicator drawing past left of text pane over margin.
<a href="https://sourceforge.net/p/scintilla/bugs/2373/">Bug #2373</a>,
<a href="https://sourceforge.net/p/scintilla/bugs/1956/">Bug #1956</a>.
</li>
<li>
On Qt, allow scrolling with mouse wheel when scroll bar hidden.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla532.zip">Release 5.3.2</a>
</h3>

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20221206" />
<meta name="Date.Modified" content="20230208" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
#versionlist {
@ -56,8 +56,8 @@
GTK, and macOS</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3"> Release version 5.3.2<br />
Site last modified December 6 2022</font>
<font color="#FFCC99" size="3"> Release version 5.3.3<br />
Site last modified February 8 2023</font>
</td>
<td width="20%">
&nbsp;
@ -72,12 +72,12 @@
</tr>
</table>
<ul id="versionlist">
<li>Version 5.3.3 fixes minor bugs in APIs and platform layers.</li>
<li>Version 5.3.2 adds SCI_REPLACETARGETMINIMAL to modify text without marking unchanged start and end text in change history.</li>
<li>Version 5.3.1 can represent invisible text with a character to simplify editing and provide summarized views.</li>
<li>Version 5.3.0 adds change history.</li>
<li>Version 5.2.4 fixes failures on GTK with multi-threaded layout.</li>
<li>Version 5.2.3 adds 64-bit safe APIs and fixes scrollbar on GTK with Xorg.</li>
<li>Version 5.2.2 on GTK, scroll horizontally with Shift + Scroll Wheel.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

View File

@ -322,6 +322,10 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
G_CALLBACK(Commit), this);
g_signal_connect(G_OBJECT(im_context.get()), "preedit_changed",
G_CALLBACK(PreeditChanged), this);
g_signal_connect(G_OBJECT(im_context.get()), "retrieve-surrounding",
G_CALLBACK(RetrieveSurrounding), this);
g_signal_connect(G_OBJECT(im_context.get()), "delete-surrounding",
G_CALLBACK(DeleteSurrounding), this);
gtk_im_context_set_client_window(im_context.get(), WindowFromWidget(widget));
GtkWidget *widtxt = PWidget(wText); // // No code inside the G_OBJECT macro
@ -2000,7 +2004,7 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) {
// where the X11 server already has an adaptive scrolling algorithm
// that fights with this one
int cLineScroll;
#if defined(__APPLE__) && !defined(GDK_WINDOWING_QUARTZ)
#if (defined(__APPLE__) || defined(PLAT_GTK_WIN32)) && !defined(GDK_WINDOWING_QUARTZ)
cLineScroll = sciThis->linesPerScroll;
if (cLineScroll == 0)
cLineScroll = 4;
@ -2605,6 +2609,65 @@ void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) {
}
}
bool ScintillaGTK::RetrieveSurroundingThis(GtkIMContext *context) {
try {
const Sci::Position pos = CurrentPosition();
const int line = pdoc->LineFromPosition(pos);
const Sci::Position startByte = pdoc->LineStart(line);
const Sci::Position endByte = pdoc->LineEnd(line);
std::string utf8Text;
gint cursorIndex; // index of the cursor inside utf8Text, in bytes
const char *charSetBuffer;
if (IsUnicodeMode() || ! *(charSetBuffer = CharacterSetID())) {
utf8Text = RangeText(startByte, endByte);
cursorIndex = pos - startByte;
} else {
// Need to convert
std::string tmpbuf = RangeText(startByte, pos);
utf8Text = ConvertText(&tmpbuf[0], tmpbuf.length(), "UTF-8", charSetBuffer, false);
cursorIndex = utf8Text.length();
if (endByte > pos) {
tmpbuf = RangeText(pos, endByte);
utf8Text += ConvertText(&tmpbuf[0], tmpbuf.length(), "UTF-8", charSetBuffer, false);
}
}
gtk_im_context_set_surrounding(context, &utf8Text[0], utf8Text.length(), cursorIndex);
return true;
} catch (...) {
errorStatus = Status::Failure;
}
return false;
}
gboolean ScintillaGTK::RetrieveSurrounding(GtkIMContext *context, ScintillaGTK *sciThis) {
return sciThis->RetrieveSurroundingThis(context);
}
bool ScintillaGTK::DeleteSurroundingThis(GtkIMContext *, gint characterOffset, gint characterCount) {
try {
const Sci::Position startByte = pdoc->GetRelativePosition(CurrentPosition(), characterOffset);
if (startByte == INVALID_POSITION)
return false;
const Sci::Position endByte = pdoc->GetRelativePosition(startByte, characterCount);
if (endByte == INVALID_POSITION)
return false;
return pdoc->DeleteChars(startByte, endByte - startByte);
} catch (...) {
errorStatus = Status::Failure;
}
return false;
}
gboolean ScintillaGTK::DeleteSurrounding(GtkIMContext *context, gint characterOffset, gint characterCount, ScintillaGTK *sciThis) {
return sciThis->DeleteSurroundingThis(context, characterOffset, characterCount);
}
void ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void *) {
RealizeText(widget, nullptr);
}

View File

@ -235,6 +235,11 @@ private:
void PreeditChangedInlineThis();
void PreeditChangedWindowedThis();
static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis);
bool RetrieveSurroundingThis(GtkIMContext *context);
static gboolean RetrieveSurrounding(GtkIMContext *context, ScintillaGTK *sciThis);
bool DeleteSurroundingThis(GtkIMContext *context, gint characterOffset, gint characterCount);
static gboolean DeleteSurrounding(GtkIMContext *context, gint characterOffset, gint characterCount,
ScintillaGTK *sciThis);
void MoveImeCarets(Sci::Position pos);
void DrawImeIndicator(int indicator, Sci::Position len);
void SetCandidateWindowPos();

View File

@ -13,7 +13,7 @@ TEMPLATE = lib
CONFIG += lib_bundle
CONFIG += c++1z
VERSION = 5.3.2
VERSION = 5.3.3
SOURCES += \
ScintillaEdit.cpp \

View File

@ -545,7 +545,7 @@ void SurfaceImpl::DrawTextTransparent(PRectangle rc,
void SurfaceImpl::SetClip(PRectangle rc)
{
GetPainter()->save();
GetPainter()->setClipRect(QRectFFromPRect(rc));
GetPainter()->setClipRect(QRectFFromPRect(rc), Qt::IntersectClip);
}
void SurfaceImpl::PopClip()

View File

@ -169,10 +169,7 @@ int wheelEventYDelta(QWheelEvent *event) {
void ScintillaEditBase::wheelEvent(QWheelEvent *event)
{
if (isWheelEventHorizontal(event)) {
if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff)
event->ignore();
else
QAbstractScrollArea::wheelEvent(event);
QAbstractScrollArea::wheelEvent(event);
} else {
if (QApplication::keyboardModifiers() & Qt::ControlModifier) {
// Zoom! We play with the font sizes in the styles.
@ -183,13 +180,8 @@ void ScintillaEditBase::wheelEvent(QWheelEvent *event)
sqt->KeyCommand(Message::ZoomOut);
}
} else {
// Ignore wheel events when the scroll bars are disabled.
if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
event->ignore();
} else {
// Scroll
QAbstractScrollArea::wheelEvent(event);
}
// Scroll
QAbstractScrollArea::wheelEvent(event);
}
}
}

View File

@ -12,7 +12,7 @@ TEMPLATE = lib
CONFIG += lib_bundle
CONFIG += c++1z
VERSION = 5.3.2
VERSION = 5.3.3
SOURCES += \
PlatQt.cpp \

View File

@ -225,27 +225,27 @@ void Document::RemoveLine(Sci::Line line) {
}
LineMarkers *Document::Markers() const noexcept {
return dynamic_cast<LineMarkers *>(perLineData[ldMarkers].get());
return static_cast<LineMarkers *>(perLineData[ldMarkers].get());
}
LineLevels *Document::Levels() const noexcept {
return dynamic_cast<LineLevels *>(perLineData[ldLevels].get());
return static_cast<LineLevels *>(perLineData[ldLevels].get());
}
LineState *Document::States() const noexcept {
return dynamic_cast<LineState *>(perLineData[ldState].get());
return static_cast<LineState *>(perLineData[ldState].get());
}
LineAnnotation *Document::Margins() const noexcept {
return dynamic_cast<LineAnnotation *>(perLineData[ldMargin].get());
return static_cast<LineAnnotation *>(perLineData[ldMargin].get());
}
LineAnnotation *Document::Annotations() const noexcept {
return dynamic_cast<LineAnnotation *>(perLineData[ldAnnotation].get());
return static_cast<LineAnnotation *>(perLineData[ldAnnotation].get());
}
LineAnnotation *Document::EOLAnnotations() const noexcept {
return dynamic_cast<LineAnnotation *>(perLineData[ldEOLAnnotation].get());
return static_cast<LineAnnotation *>(perLineData[ldEOLAnnotation].get());
}
LineEndType Document::LineEndTypesSupported() const {
@ -512,7 +512,7 @@ Sci::Position Document::VCHomePosition(Sci::Position position) const {
const Sci::Position startPosition = LineStart(line);
const Sci::Position endLine = LineEnd(line);
Sci::Position startText = startPosition;
while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t'))
while (startText < endLine && IsSpaceOrTab(cb.CharAt(startText)))
startText++;
if (position == startText)
return startPosition;
@ -558,8 +558,8 @@ int SCI_METHOD Document::GetLevel(Sci_Position line) const {
return Levels()->GetLevel(line);
}
FoldLevel Document::GetFoldLevel(Sci_Position line) const {
return static_cast<FoldLevel>(Levels()->GetLevel(line));
FoldLevel Document::GetFoldLevel(Sci_Position line) const noexcept {
return Levels()->GetFoldLevel(line);
}
void Document::ClearLevels() {
@ -597,21 +597,8 @@ Sci::Line Document::GetLastChild(Sci::Line lineParent, std::optional<FoldLevel>
return lineMaxSubord;
}
Sci::Line Document::GetFoldParent(Sci::Line line) const {
const FoldLevel level = LevelNumberPart(GetFoldLevel(line));
Sci::Line lineLook = line - 1;
while ((lineLook > 0) && (
(!LevelIsHeader(GetFoldLevel(lineLook))) ||
(LevelNumberPart(GetFoldLevel(lineLook)) >= level))
) {
lineLook--;
}
if (LevelIsHeader(GetFoldLevel(lineLook)) &&
(LevelNumberPart(GetFoldLevel(lineLook)) < level)) {
return lineLook;
} else {
return -1;
}
Sci::Line Document::GetFoldParent(Sci::Line line) const noexcept {
return Levels()->GetFoldParent(line);
}
void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sci::Line line, Sci::Line lastLine) {
@ -1576,13 +1563,12 @@ Sci::Position Document::SetLineIndentation(Sci::Line line, Sci::Position indent)
if (indent < 0)
indent = 0;
if (indent != indentOfLine) {
std::string linebuf = CreateIndentation(indent, tabInChars, !useTabs);
const std::string linebuf = CreateIndentation(indent, tabInChars, !useTabs);
const Sci::Position thisLineStart = LineStart(line);
const Sci::Position indentPos = GetLineIndentPosition(line);
UndoGroup ug(this);
DeleteChars(thisLineStart, indentPos - thisLineStart);
return thisLineStart + InsertString(thisLineStart, linebuf.c_str(),
linebuf.length());
return thisLineStart + InsertString(thisLineStart, linebuf);
} else {
return GetLineIndentPosition(line);
}
@ -1719,7 +1705,8 @@ void Document::ConvertLineEnds(EndOfLine eolModeSet) {
UndoGroup ug(this);
for (Sci::Position pos = 0; pos < Length(); pos++) {
if (cb.CharAt(pos) == '\r') {
const char ch = cb.CharAt(pos);
if (ch == '\r') {
if (cb.CharAt(pos + 1) == '\n') {
// CRLF
if (eolModeSet == EndOfLine::Cr) {
@ -1739,7 +1726,7 @@ void Document::ConvertLineEnds(EndOfLine eolModeSet) {
pos--;
}
}
} else if (cb.CharAt(pos) == '\n') {
} else if (ch == '\n') {
// LF
if (eolModeSet == EndOfLine::CrLf) {
pos += InsertString(pos, "\r", 1); // Insert CR
@ -1753,6 +1740,16 @@ void Document::ConvertLineEnds(EndOfLine eolModeSet) {
}
std::string_view Document::EOLString() const noexcept {
if (eolMode == EndOfLine::CrLf) {
return "\r\n";
} else if (eolMode == EndOfLine::Cr) {
return "\r";
} else {
return "\n";
}
}
DocumentOption Document::Options() const noexcept {
return (IsLarge() ? DocumentOption::TextLarge : DocumentOption::Default) |
(cb.HasStyles() ? DocumentOption::Default : DocumentOption::StylesNone);

View File

@ -420,6 +420,7 @@ public:
void Indent(bool forwards, Sci::Line lineBottom, Sci::Line lineTop);
static std::string TransformLineEnds(const char *s, size_t len, Scintilla::EndOfLine eolModeWanted);
void ConvertLineEnds(Scintilla::EndOfLine eolModeSet);
std::string_view EOLString() const noexcept;
void SetReadOnly(bool set) { cb.SetReadOnly(set); }
bool IsReadOnly() const noexcept { return cb.IsReadOnly(); }
bool IsLarge() const noexcept { return cb.IsLarge(); }
@ -461,10 +462,10 @@ public:
int SCI_METHOD SetLevel(Sci_Position line, int level) override;
int SCI_METHOD GetLevel(Sci_Position line) const override;
Scintilla::FoldLevel GetFoldLevel(Sci_Position line) const;
Scintilla::FoldLevel GetFoldLevel(Sci_Position line) const noexcept;
void ClearLevels();
Sci::Line GetLastChild(Sci::Line lineParent, std::optional<Scintilla::FoldLevel> level = {}, Sci::Line lastLine = -1);
Sci::Line GetFoldParent(Sci::Line line) const;
Sci::Line GetFoldParent(Sci::Line line) const noexcept;
void GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sci::Line line, Sci::Line lastLine);
Sci::Position ExtendWordSelect(Sci::Position pos, int delta, bool onlyWordCharacters=false) const;

File diff suppressed because it is too large Load Diff

View File

@ -133,32 +133,29 @@ public:
Sci::Line DisplayFromPosition(Surface *surface, const EditModel &model, Sci::Position pos, const ViewStyle &vs);
Sci::Position StartEndDisplayLine(Surface *surface, const EditModel &model, Sci::Position pos, bool start, const ViewStyle &vs);
void DrawIndentGuide(Surface *surface, Sci::Line lineVisible, int lineHeight, XYPOSITION start, PRectangle rcSegment, bool highlight);
void DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine,
Sci::Line line, Sci::Position lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart,
std::optional<ColourRGBA> background);
private:
void DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Position lineEnd, XYPOSITION subLineStart, ColourOptional background);
void DrawFoldDisplayText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase);
Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYPOSITION subLineStart, DrawPhase phase);
void DrawEOLAnnotationText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase);
Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYPOSITION subLineStart, DrawPhase phase);
void DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, int xStart, PRectangle rcLine, int subLine, DrawPhase phase);
void DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line lineDoc,
int xStart, PRectangle rcLine, int subLine) const;
void DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine,
Range lineRange, Sci::Position posLineStart, int xStart,
int subLine, std::optional<ColourRGBA> background) const;
void DrawForeground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line lineVisible,
PRectangle rcLine, Range lineRange, Sci::Position posLineStart, int xStart,
int subLine, std::optional<ColourRGBA> background);
void DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line lineDoc, int xStart, PRectangle rcLine, int subLine) const;
void DrawIndentGuide(Surface *surface, XYPOSITION start, PRectangle rcSegment, bool highlight, bool offset);
void DrawForeground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
int xStart, PRectangle rcLine, int subLine, Sci::Line lineVisible, Range lineRange, Sci::Position posLineStart,
ColourOptional background);
void DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, Sci::Line lineVisible, PRectangle rcLine, int xStart, int subLine);
void DrawLine(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line,
Sci::Line lineVisible, int xStart, PRectangle rcLine, int subLine, DrawPhase phase);
void PaintText(Surface *surfaceWindow, const EditModel &model, PRectangle rcArea, PRectangle rcClient,
const ViewStyle &vsDraw);
void FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, PRectangle rcArea, int subLine) const;
Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Line lineVisible);
void DrawLine(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, Sci::Line lineVisible, int xStart, PRectangle rcLine, int subLine, DrawPhase phase);
public:
void PaintText(Surface *surfaceWindow, const EditModel &model, const ViewStyle &vsDraw,
PRectangle rcArea, PRectangle rcClient);
Sci::Position FormatRange(bool draw, CharacterRangeFull chrg, Rectangle rc, Surface *surface, Surface *surfaceMeasure,
const EditModel &model, const ViewStyle &vs);
};

View File

@ -801,9 +801,7 @@ void Editor::MultipleSelectAdd(AddNumber addNumber) {
bool Editor::RangeContainsProtected(Sci::Position start, Sci::Position end) const noexcept {
if (vs.ProtectionActive()) {
if (start > end) {
const Sci::Position t = start;
start = end;
end = t;
std::swap(start, end);
}
for (Sci::Position pos = start; pos < end; pos++) {
if (vs.styles[pdoc->StyleIndexAt(pos)].IsProtected())
@ -1012,6 +1010,7 @@ void Editor::VerticalCentreCaret() {
const Sci::Line newTop = lineDisplay - (LinesOnScreen() / 2);
if (topLine != newTop) {
SetTopLine(newTop > 0 ? newTop : 0);
SetVerticalScrollPos();
RedrawRect(GetClientRectangle());
}
}
@ -1058,8 +1057,7 @@ void Editor::MoveSelectedLines(int lineDelta) {
}
SetSelection(selectionStart, selectionEnd);
SelectionText selectedText;
CopySelectionRange(&selectedText);
const std::string selectedText = RangeText(selectionStart, selectionEnd);
const Point currentLocation = LocationFromPosition(CurrentPosition());
const Sci::Line currentLine = LineFromLocation(currentLocation);
@ -1068,14 +1066,14 @@ void Editor::MoveSelectedLines(int lineDelta) {
SetSelection(pdoc->MovePositionOutsideChar(selectionStart - 1, -1), selectionEnd);
ClearSelection();
const char *eol = StringFromEOLMode(pdoc->eolMode);
const std::string_view eol = pdoc->EOLString();
if (currentLine + lineDelta >= pdoc->LinesTotal())
pdoc->InsertString(pdoc->Length(), eol, strlen(eol));
pdoc->InsertString(pdoc->Length(), eol);
GoToLine(currentLine + lineDelta);
Sci::Position selectionLength = pdoc->InsertString(CurrentPosition(), selectedText.Data(), selectedText.Length());
Sci::Position selectionLength = pdoc->InsertString(CurrentPosition(), selectedText);
if (appendEol) {
const Sci::Position lengthInserted = pdoc->InsertString(CurrentPosition() + selectionLength, eol, strlen(eol));
const Sci::Position lengthInserted = pdoc->InsertString(CurrentPosition() + selectionLength, eol);
selectionLength += lengthInserted;
}
SetSelection(CurrentPosition(), CurrentPosition() + selectionLength);
@ -1184,9 +1182,11 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran
// It should be possible to scroll the window to show the caret,
// but this fails to remove the caret on GTK+
if (bSlop) { // A margin is defined
Sci::Line yMoveT, yMoveB;
Sci::Line yMoveT = 0;
Sci::Line yMoveB = 0;
if (bStrict) {
Sci::Line yMarginT, yMarginB;
Sci::Line yMarginT = 0;
Sci::Line yMarginB = 0;
if (!FlagSet(options, XYScrollOptions::useMargin)) {
// In drag mode, avoid moves
// otherwise, a double click will select several lines.
@ -1281,9 +1281,11 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran
const bool bEven = FlagSet(policies.x.policy, CaretPolicy::Even);
if (bSlop) { // A margin is defined
int xMoveL, xMoveR;
int xMoveL = 0;
int xMoveR = 0;
if (bStrict) {
int xMarginL, xMarginR;
int xMarginL = 0;
int xMarginR = 0;
if (!FlagSet(options, XYScrollOptions::useMargin)) {
// In drag mode, avoid moves unless very near of the margin
// otherwise, a simple click will select text.
@ -1624,33 +1626,21 @@ bool Editor::WrapLines(WrapScope ws) {
void Editor::LinesJoin() {
if (!RangeContainsProtected(targetRange.start.Position(), targetRange.end.Position())) {
UndoGroup ug(pdoc);
bool prevNonWS = true;
for (Sci::Position pos = targetRange.start.Position(); pos < targetRange.end.Position(); pos++) {
if (pdoc->IsPositionInLineEnd(pos)) {
targetRange.end.Add(-pdoc->LenChar(pos));
pdoc->DelChar(pos);
if (prevNonWS) {
// Ensure at least one space separating previous lines
const Sci::Position lengthInserted = pdoc->InsertString(pos, " ", 1);
targetRange.end.Add(lengthInserted);
}
} else {
prevNonWS = pdoc->CharAt(pos) != ' ';
const Sci::Line line = pdoc->SciLineFromPosition(targetRange.start.Position());
for (Sci::Position pos = pdoc->LineEnd(line); pos < targetRange.end.Position(); pos = pdoc->LineEnd(line)) {
const char chPrev = pdoc->CharAt(pos - 1);
const Sci::Position widthChar = pdoc->LenChar(pos);
targetRange.end.Add(-widthChar);
pdoc->DeleteChars(pos, widthChar);
if (chPrev != ' ') {
// Ensure at least one space separating previous lines
const Sci::Position lengthInserted = pdoc->InsertString(pos, " ", 1);
targetRange.end.Add(lengthInserted);
}
}
}
}
const char *Editor::StringFromEOLMode(EndOfLine eolMode) noexcept {
if (eolMode == EndOfLine::CrLf) {
return "\r\n";
} else if (eolMode == EndOfLine::Cr) {
return "\r";
} else {
return "\n";
}
}
void Editor::LinesSplit(int pixelWidth) {
if (!RangeContainsProtected(targetRange.start.Position(), targetRange.end.Position())) {
if (pixelWidth == 0) {
@ -1659,7 +1649,7 @@ void Editor::LinesSplit(int pixelWidth) {
}
const Sci::Line lineStart = pdoc->SciLineFromPosition(targetRange.start.Position());
Sci::Line lineEnd = pdoc->SciLineFromPosition(targetRange.end.Position());
const char *eol = StringFromEOLMode(pdoc->eolMode);
const std::string_view eol = pdoc->EOLString();
UndoGroup ug(pdoc);
for (Sci::Line line = lineStart; line <= lineEnd; line++) {
AutoSurface surface(this);
@ -1670,8 +1660,7 @@ void Editor::LinesSplit(int pixelWidth) {
Sci::Position lengthInsertedTotal = 0;
for (int subLine = 1; subLine < ll->lines; subLine++) {
const Sci::Position lengthInserted = pdoc->InsertString(
posLineStart + lengthInsertedTotal + ll->LineStart(subLine),
eol, strlen(eol));
posLineStart + lengthInsertedTotal + ll->LineStart(subLine), eol);
targetRange.end.Add(lengthInserted);
lengthInsertedTotal += lengthInserted;
}
@ -1820,7 +1809,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
return;
}
view.PaintText(surfaceWindow, *this, rcArea, rcClient, vs);
view.PaintText(surfaceWindow, *this, vs, rcArea, rcClient);
if (horizontalScrollBarVisible && trackLineWidth && (view.lineWidthMaxSeen > scrollWidth)) {
scrollWidth = view.lineWidthMaxSeen;
@ -1927,8 +1916,8 @@ Sci::Position Editor::RealizeVirtualSpace(Sci::Position position, Sci::Position
if (indent == position) {
return pdoc->SetLineIndentation(line, pdoc->GetLineIndentation(line) + virtualSpace);
} else {
std::string spaceText(virtualSpace, ' ');
const Sci::Position lengthInserted = pdoc->InsertString(position, spaceText.c_str(), virtualSpace);
const std::string spaceText(virtualSpace, ' ');
const Sci::Position lengthInserted = pdoc->InsertString(position, spaceText);
position += lengthInserted;
}
}
@ -1995,7 +1984,7 @@ void Editor::InsertCharacter(std::string_view sv, CharacterSource charSource) {
}
}
positionInsert = RealizeVirtualSpace(positionInsert, currentSel->caret.VirtualSpace());
const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, sv.data(), sv.length());
const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, sv);
if (lengthInserted > 0) {
currentSel->caret.SetPosition(positionInsert + lengthInserted);
currentSel->anchor.SetPosition(positionInsert + lengthInserted);
@ -2129,9 +2118,8 @@ void Editor::InsertPasteShape(const char *text, Sci::Position len, PasteShape sh
Sci::Position lengthInserted = pdoc->InsertString(insertPos, text, len);
// add the newline if necessary
if ((len > 0) && (text[len - 1] != '\n' && text[len - 1] != '\r')) {
const char *endline = StringFromEOLMode(pdoc->eolMode);
const Sci::Position length = strlen(endline);
lengthInserted += pdoc->InsertString(insertPos + lengthInserted, endline, length);
const std::string_view endline = pdoc->EOLString();
lengthInserted += pdoc->InsertString(insertPos + lengthInserted, endline);
}
if (sel.MainCaret() == insertPos) {
SetEmptySelection(sel.MainCaret() + lengthInserted);
@ -2225,10 +2213,8 @@ void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Posit
if ((ptr[i] == '\r') || (!prevCr))
line++;
if (line >= pdoc->LinesTotal()) {
if (pdoc->eolMode != EndOfLine::Lf)
pdoc->InsertString(pdoc->Length(), "\r", 1);
if (pdoc->eolMode != EndOfLine::Cr)
pdoc->InsertString(pdoc->Length(), "\n", 1);
const std::string_view eol = pdoc->EOLString();
pdoc->InsertString(pdoc->LengthNoExcept(), eol);
}
// Pad the end of lines with spaces if required
sel.RangeMain().caret.SetPosition(PositionFromLineX(line, xInsert));
@ -3030,10 +3016,8 @@ void Editor::LineTranspose() {
pdoc->DeleteChars(startPrevious, linePrevious.length());
startCurrent -= linePrevious.length();
startCurrent += pdoc->InsertString(startPrevious, lineCurrent.c_str(),
lineCurrent.length());
pdoc->InsertString(startCurrent, linePrevious.c_str(),
linePrevious.length());
startCurrent += pdoc->InsertString(startPrevious, lineCurrent);
pdoc->InsertString(startCurrent, linePrevious);
// Move caret to start of current line
MovePositionTo(SelectionPosition(startCurrent));
}
@ -3060,8 +3044,8 @@ void Editor::LineReverse() {
pdoc->DeleteChars(lineStart2, lineLen2);
pdoc->DeleteChars(lineStart1, lineLen1);
lineStart2 -= lineLen1;
pdoc->InsertString(lineStart2, line1.c_str(), lineLen1);
pdoc->InsertString(lineStart1, line2.c_str(), lineLen2);
pdoc->InsertString(lineStart2, line1);
pdoc->InsertString(lineStart1, line2);
}
// Wholly select all affected lines
sel.RangeMain() = SelectionRange(pdoc->LineStart(lineStart),
@ -3073,11 +3057,9 @@ void Editor::Duplicate(bool forLine) {
forLine = true;
}
UndoGroup ug(pdoc);
const char *eol = "";
Sci::Position eolLen = 0;
std::string_view eol;
if (forLine) {
eol = StringFromEOLMode(pdoc->eolMode);
eolLen = strlen(eol);
eol = pdoc->EOLString();
}
for (size_t r=0; r<sel.Count(); r++) {
SelectionPosition start = sel.Range(r).Start();
@ -3088,10 +3070,10 @@ void Editor::Duplicate(bool forLine) {
end = SelectionPosition(pdoc->LineEnd(line));
}
std::string text = RangeText(start.Position(), end.Position());
Sci::Position lengthInserted = eolLen;
Sci::Position lengthInserted = 0;
if (forLine)
lengthInserted = pdoc->InsertString(end.Position(), eol, eolLen);
pdoc->InsertString(end.Position() + lengthInserted, text.c_str(), text.length());
lengthInserted = pdoc->InsertString(end.Position(), eol);
pdoc->InsertString(end.Position() + lengthInserted, text);
}
if (sel.Count() && sel.IsRectangular()) {
SelectionPosition last = sel.Last();
@ -3128,11 +3110,11 @@ void Editor::NewLine() {
// Insert each line end
size_t countInsertions = 0;
const std::string_view eol = pdoc->EOLString();
for (size_t r = 0; r < sel.Count(); r++) {
sel.Range(r).ClearVirtualSpace();
const char *eol = StringFromEOLMode(pdoc->eolMode);
const Sci::Position positionInsert = sel.Range(r).caret.Position();
const Sci::Position insertLength = pdoc->InsertString(positionInsert, eol, strlen(eol));
const Sci::Position insertLength = pdoc->InsertString(positionInsert, eol);
if (insertLength > 0) {
sel.Range(r) = SelectionRange(positionInsert + insertLength);
countInsertions++;
@ -3142,16 +3124,12 @@ void Editor::NewLine() {
// Perform notifications after all the changes as the application may change the
// selections in response to the characters.
for (size_t i = 0; i < countInsertions; i++) {
const char *eol = StringFromEOLMode(pdoc->eolMode);
while (*eol) {
NotifyChar(*eol, CharacterSource::DirectInput);
for (const char ch : eol) {
NotifyChar(ch, CharacterSource::DirectInput);
if (recordingMacro) {
char txt[2];
txt[0] = *eol;
txt[1] = '\0';
const char txt[2] = { ch, '\0' };
NotifyMacroRecord(Message::ReplaceSel, 0, reinterpret_cast<sptr_t>(txt));
}
eol++;
}
}
@ -4038,8 +4016,7 @@ void Editor::Indent(bool forwards) {
if (numSpaces < 1)
numSpaces = pdoc->tabInChars;
const std::string spaceText(numSpaces, ' ');
const Sci::Position lengthInserted = pdoc->InsertString(caretPosition, spaceText.c_str(),
spaceText.length());
const Sci::Position lengthInserted = pdoc->InsertString(caretPosition, spaceText);
sel.Range(r) = SelectionRange(caretPosition + lengthInserted);
}
}
@ -4143,14 +4120,14 @@ Sci::Position Editor::FindTextFull(
pdoc->SetCaseFolder(CaseFolderForEncoding());
try {
const Sci::Position pos = pdoc->FindText(
static_cast<Sci::Position>(ft->chrg.cpMin),
static_cast<Sci::Position>(ft->chrg.cpMax),
ft->chrg.cpMin,
ft->chrg.cpMax,
ft->lpstrText,
static_cast<FindOption>(wParam),
&lengthFound);
if (pos != -1) {
ft->chrgText.cpMin = static_cast<Sci_PositionCR>(pos);
ft->chrgText.cpMax = static_cast<Sci_PositionCR>(pos + lengthFound);
ft->chrgText.cpMin = pos;
ft->chrgText.cpMax = pos + lengthFound;
}
return pos;
} catch (RegexError &) {
@ -4423,7 +4400,7 @@ void Editor::DropAt(SelectionPosition position, const char *value, size_t length
position = MovePositionOutsideChar(position, sel.MainCaret() - position.Position());
position = RealizeVirtualSpace(position);
const Sci::Position lengthInserted = pdoc->InsertString(
position.Position(), convertedText.c_str(), convertedText.length());
position.Position(), convertedText);
if (lengthInserted > 0) {
SelectionPosition posAfterInsertion = position;
posAfterInsertion.Add(lengthInserted);
@ -5782,12 +5759,11 @@ void Editor::AddStyledText(const char *buffer, Sci::Position appendLength) {
// The buffer consists of alternating character bytes and style bytes
const Sci::Position textLength = appendLength / 2;
std::string text(textLength, '\0');
Sci::Position i;
for (i = 0; i < textLength; i++) {
for (Sci::Position i = 0; i < textLength; i++) {
text[i] = buffer[i*2];
}
const Sci::Position lengthInserted = pdoc->InsertString(CurrentPosition(), text.c_str(), textLength);
for (i = 0; i < textLength; i++) {
const Sci::Position lengthInserted = pdoc->InsertString(CurrentPosition(), text);
for (Sci::Position i = 0; i < textLength; i++) {
text[i] = buffer[i*2+1];
}
pdoc->StartStyling(CurrentPosition());
@ -5871,8 +5847,8 @@ void Editor::StyleSetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {
const int classified = UTF8Classify(utf8);
if (!(classified & UTF8MaskInvalid)) {
// valid UTF-8
int len = classified & UTF8MaskWidth;
for (int i=0; i<len && i<4; i++)
const int len = classified & UTF8MaskWidth;
for (int i=0; i<len && i<UTF8MaxBytes; i++)
*rep++ = *utf8++;
}
*rep = 0;
@ -7474,10 +7450,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
InvalidateStyleRedraw();
break;
case Message::GetCaretLineBack:
if (vs.ElementColour(Element::CaretLineBack))
return vs.ElementColour(Element::CaretLineBack)->OpaqueRGB();
else
return 0;
return vs.ElementColourForced(Element::CaretLineBack).OpaqueRGB();
case Message::SetCaretLineBack:
vs.SetElementRGB(Element::CaretLineBack, static_cast<int>(wParam));
@ -7688,7 +7661,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::GetSelAlpha:
if (vs.selection.layer == Layer::Base)
return static_cast<sptr_t>(Alpha::NoAlpha);
return vs.ElementColour(Element::SelectionBack)->GetAlpha();
return vs.ElementColourForced(Element::SelectionBack).GetAlpha();
case Message::GetSelEOLFilled:
return vs.selection.eolFilled;
@ -7727,7 +7700,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
break;
case Message::GetCaretFore:
return vs.ElementColour(Element::Caret)->OpaqueRGB();
return vs.ElementColourForced(Element::Caret).OpaqueRGB();
case Message::SetCaretStyle:
if (static_cast<CaretStyle>(wParam) <= (CaretStyle::Block | CaretStyle::OverstrikeBlock | CaretStyle::Curses | CaretStyle::BlockAfter))
@ -8748,7 +8721,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::GetAdditionalSelAlpha:
if (vs.selection.layer == Layer::Base)
return static_cast<sptr_t>(Alpha::NoAlpha);
return vs.ElementColour(Element::SelectionAdditionalBack)->GetAlpha();
return vs.ElementColourForced(Element::SelectionAdditionalBack).GetAlpha();
case Message::SetAdditionalCaretFore:
vs.elementColours[Element::CaretAdditional] = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam));
@ -8756,7 +8729,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
break;
case Message::GetAdditionalCaretFore:
return vs.ElementColour(Element::CaretAdditional)->OpaqueRGB();
return vs.ElementColourForced(Element::CaretAdditional).OpaqueRGB();
case Message::RotateSelection:
sel.RotateMain();

View File

@ -608,8 +608,6 @@ protected: // ScintillaBase subclass needs access to much of Editor
Scintilla::sptr_t StyleGetMessage(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
void SetSelectionNMessage(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
static const char *StringFromEOLMode(Scintilla::EndOfLine eolMode) noexcept;
// Coercion functions for transforming WndProc parameters into pointers
static void *PtrFromSPtr(Scintilla::sptr_t lParam) noexcept {
return reinterpret_cast<void *>(lParam);

View File

@ -66,6 +66,9 @@ public:
constexpr bool Intersects(Interval other) const noexcept {
return (right > other.left) && (left < other.right);
}
constexpr Interval Offset(XYPOSITION offset) const noexcept {
return {left + offset, right + offset};
}
};
/**
@ -112,6 +115,10 @@ public:
return (right > other.left) && (left < other.right) &&
(bottom > other.top) && (top < other.bottom);
}
constexpr bool Intersects(Interval horizontalBounds) const noexcept {
return (right > horizontalBounds.left) && (left < horizontalBounds.right);
}
void Move(XYPOSITION xDelta, XYPOSITION yDelta) noexcept {
left += xDelta;
top += yDelta;
@ -119,6 +126,10 @@ public:
bottom += yDelta;
}
PRectangle WithHorizontalBounds(Interval horizontal) const noexcept {
return PRectangle(horizontal.left, top, horizontal.right, bottom);
}
constexpr PRectangle Inset(XYPOSITION delta) const noexcept {
return PRectangle(left + delta, top + delta, right - delta, bottom - delta);
}
@ -200,16 +211,18 @@ public:
// Red, green and blue values as bytes 0..255
constexpr unsigned char GetRed() const noexcept {
return co & 0xff;
return co & 0xffU;
}
constexpr unsigned char GetGreen() const noexcept {
return (co >> 8) & 0xff;
return (co >> 8) & 0xffU;
}
constexpr unsigned char GetBlue() const noexcept {
return (co >> 16) & 0xff;
return (co >> 16) & 0xffU;
}
constexpr unsigned char GetAlpha() const noexcept {
return (co >> 24) & 0xff;
// Use a temporary here to prevent a 'Wconversion' warning from GCC
const int shifted = co >> 24;
return shifted & 0xffU;
}
// Red, green, blue, and alpha values as float 0..1.0

View File

@ -264,11 +264,28 @@ int LineLevels::SetLevel(Sci::Line line, int level, Sci::Line lines) {
}
int LineLevels::GetLevel(Sci::Line line) const noexcept {
if (levels.Length() && (line >= 0) && (line < levels.Length())) {
if ((line >= 0) && (line < levels.Length())) {
return levels[line];
} else {
return static_cast<int>(Scintilla::FoldLevel::Base);
}
return static_cast<int>(Scintilla::FoldLevel::Base);
}
Scintilla::FoldLevel LineLevels::GetFoldLevel(Sci::Line line) const noexcept {
if ((line >= 0) && (line < levels.Length())) {
return static_cast<FoldLevel>(levels[line]);
}
return Scintilla::FoldLevel::Base;
}
Sci::Line LineLevels::GetFoldParent(Sci::Line line) const noexcept {
const FoldLevel level = LevelNumberPart(GetFoldLevel(line));
for (Sci::Line lineLook = line - 1; lineLook >= 0; lineLook--) {
const FoldLevel levelTry = GetFoldLevel(lineLook);
if (LevelIsHeader(levelTry) && LevelNumberPart(levelTry) < level) {
return lineLook;
}
}
return -1;
}
void LineState::Init() {

View File

@ -75,6 +75,8 @@ public:
void ClearLevels();
int SetLevel(Sci::Line line, int level, Sci::Line lines);
int GetLevel(Sci::Line line) const noexcept;
FoldLevel GetFoldLevel(Sci::Line line) const noexcept;
Sci::Line GetFoldParent(Sci::Line line) const noexcept;
};
class LineState : public PerLine {

View File

@ -314,10 +314,76 @@ XYPOSITION LineLayout::XInLine(Sci::Position index) const noexcept {
return positions[numCharsInLine] + 1.0;
}
Interval LineLayout::Span(int start, int end) const noexcept {
return { positions[start], positions[end] };
}
Interval LineLayout::SpanByte(int index) const noexcept {
return Span(index, index+1);
}
int LineLayout::EndLineStyle() const noexcept {
return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0];
}
void LineLayout::WrapLine(const Document *pdoc, Sci::Position posLineStart, Wrap wrapState) {
// Document wants document positions but simpler to work in line positions
// so take care of adding and subtracting line start in a lambda.
auto CharacterBoundary = [=](Sci::Position i, Sci::Position moveDir) noexcept -> Sci::Position {
return pdoc->MovePositionOutsideChar(i + posLineStart, moveDir) - posLineStart;
};
lines = 0;
// Calculate line start positions based upon width.
Sci::Position lastLineStart = 0;
XYPOSITION startOffset = widthLine;
Sci::Position p = 0;
while (p < numCharsInLine) {
while (p < numCharsInLine && positions[p + 1] < startOffset) {
p++;
}
if (p < numCharsInLine) {
// backtrack to find lastGoodBreak
Sci::Position lastGoodBreak = p;
if (p > 0) {
lastGoodBreak = CharacterBoundary(p, -1);
}
if (wrapState != Wrap::Char) {
Sci::Position pos = lastGoodBreak;
while (pos > lastLineStart) {
// style boundary and space
if (wrapState != Wrap::WhiteSpace && (styles[pos - 1] != styles[pos])) {
break;
}
if (IsBreakSpace(chars[pos - 1]) && !IsBreakSpace(chars[pos])) {
break;
}
pos = CharacterBoundary(pos - 1, -1);
}
if (pos > lastLineStart) {
lastGoodBreak = pos;
}
}
if (lastGoodBreak == lastLineStart) {
// Try moving to start of last character
if (p > 0) {
lastGoodBreak = CharacterBoundary(p, -1);
}
if (lastGoodBreak == lastLineStart) {
// Ensure at least one character on line.
lastGoodBreak = CharacterBoundary(lastGoodBreak + 1, 1);
}
}
lastLineStart = lastGoodBreak;
AddLineStart(lastLineStart);
startOffset = positions[lastLineStart];
// take into account the space for start wrap mark and indent
startOffset += widthLine - wrapIndent;
p = lastLineStart + 1;
}
}
lines++;
}
ScreenLine::ScreenLine(
const LineLayout *ll_,
int subLine,
@ -508,21 +574,21 @@ std::shared_ptr<LineLayout> LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci:
size_t pos = 0;
if (level == LineCache::Page) {
// If first entry is this line then just reuse it.
if (!(cache[0] && (cache[0]->lineNumber == lineNumber))) {
if (!(cache[0] && (cache[0]->LineNumber() == lineNumber))) {
const size_t posForLine = EntryForLine(lineNumber);
if (lineNumber == lineCaret) {
// Use position 0 for caret line.
if (cache[0]) {
// Another line is currently in [0] so move it out to its normal position.
// Since it was recently the caret line its likely to be needed soon.
const size_t posNewForEntry0 = EntryForLine(cache[0]->lineNumber);
const size_t posNewForEntry0 = EntryForLine(cache[0]->LineNumber());
if (posForLine == posNewForEntry0) {
std::swap(cache[0], cache[posNewForEntry0]);
} else {
cache[posNewForEntry0] = std::move(cache[0]);
}
}
if (cache[posForLine] && (cache[posForLine]->lineNumber == lineNumber)) {
if (cache[posForLine] && (cache[posForLine]->LineNumber() == lineNumber)) {
// Caret line is currently somewhere else so move it to [0].
cache[0] = std::move(cache[posForLine]);
}
@ -818,6 +884,7 @@ class PositionCacheEntry {
uint16_t styleNumber;
uint16_t len;
uint16_t clock;
bool unicode;
std::unique_ptr<XYPOSITION[]> positions;
public:
PositionCacheEntry() noexcept;
@ -828,10 +895,10 @@ public:
void operator=(const PositionCacheEntry &) = delete;
void operator=(PositionCacheEntry &&) = delete;
~PositionCacheEntry();
void Set(unsigned int styleNumber_, std::string_view sv, const XYPOSITION *positions_, uint16_t clock_);
void Set(unsigned int styleNumber_, bool unicode_, std::string_view sv, const XYPOSITION *positions_, uint16_t clock_);
void Clear() noexcept;
bool Retrieve(unsigned int styleNumber_, std::string_view sv, XYPOSITION *positions_) const noexcept;
static size_t Hash(unsigned int styleNumber_, std::string_view sv) noexcept;
bool Retrieve(unsigned int styleNumber_, bool unicode_, std::string_view sv, XYPOSITION *positions_) const noexcept;
static size_t Hash(unsigned int styleNumber_, bool unicode_, std::string_view sv) noexcept;
bool NewerThan(const PositionCacheEntry &other) const noexcept;
void ResetClock() noexcept;
};
@ -854,16 +921,16 @@ public:
void SetSize(size_t size_) override;
size_t GetSize() const noexcept override;
void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
std::string_view sv, XYPOSITION *positions, bool needsLocking) override;
bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) override;
};
PositionCacheEntry::PositionCacheEntry() noexcept :
styleNumber(0), len(0), clock(0) {
styleNumber(0), len(0), clock(0), unicode(false) {
}
// Copy constructor not currently used, but needed for being element in std::vector.
PositionCacheEntry::PositionCacheEntry(const PositionCacheEntry &other) :
styleNumber(other.styleNumber), len(other.len), clock(other.clock) {
styleNumber(other.styleNumber), len(other.len), clock(other.clock), unicode(other.unicode) {
if (other.positions) {
const size_t lenData = len + (len / sizeof(XYPOSITION)) + 1;
positions = std::make_unique<XYPOSITION[]>(lenData);
@ -871,12 +938,13 @@ PositionCacheEntry::PositionCacheEntry(const PositionCacheEntry &other) :
}
}
void PositionCacheEntry::Set(unsigned int styleNumber_, std::string_view sv,
void PositionCacheEntry::Set(unsigned int styleNumber_, bool unicode_, std::string_view sv,
const XYPOSITION *positions_, uint16_t clock_) {
Clear();
styleNumber = static_cast<uint16_t>(styleNumber_);
len = static_cast<uint16_t>(sv.length());
clock = clock_;
unicode = unicode_;
if (sv.data() && positions_) {
positions = std::make_unique<XYPOSITION[]>(len + (len / sizeof(XYPOSITION)) + 1);
for (unsigned int i=0; i<len; i++) {
@ -897,8 +965,8 @@ void PositionCacheEntry::Clear() noexcept {
clock = 0;
}
bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, std::string_view sv, XYPOSITION *positions_) const noexcept {
if ((styleNumber == styleNumber_) && (len == sv.length()) &&
bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, bool unicode_, std::string_view sv, XYPOSITION *positions_) const noexcept {
if ((styleNumber == styleNumber_) && (unicode == unicode_) && (len == sv.length()) &&
(memcmp(&positions[len], sv.data(), sv.length())== 0)) {
for (unsigned int i=0; i<len; i++) {
positions_[i] = positions[i];
@ -909,10 +977,10 @@ bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, std::string_view sv
}
}
size_t PositionCacheEntry::Hash(unsigned int styleNumber_, std::string_view sv) noexcept {
size_t PositionCacheEntry::Hash(unsigned int styleNumber_, bool unicode_, std::string_view sv) noexcept {
const size_t h1 = std::hash<std::string_view>{}(sv);
const size_t h2 = std::hash<unsigned int>{}(styleNumber_);
return h1 ^ (h2 << 1);
return h1 ^ (h2 << 1) ^ static_cast<size_t>(unicode_);
}
bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) const noexcept {
@ -951,7 +1019,7 @@ size_t PositionCache::GetSize() const noexcept {
}
void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
std::string_view sv, XYPOSITION *positions, bool needsLocking) {
bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) {
const Style &style = vstyle.styles[styleNumber];
if (style.monospaceASCII) {
if (AllGraphicASCII(sv)) {
@ -969,17 +1037,17 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns
// long comments with only a single comment.
// Two way associative: try two probe positions.
const size_t hashValue = PositionCacheEntry::Hash(styleNumber, sv);
const size_t hashValue = PositionCacheEntry::Hash(styleNumber, unicode, sv);
probe = hashValue % pces.size();
std::unique_lock<std::mutex> guard(mutex, std::defer_lock);
if (needsLocking) {
guard.lock();
}
if (pces[probe].Retrieve(styleNumber, sv, positions)) {
if (pces[probe].Retrieve(styleNumber, unicode, sv, positions)) {
return;
}
const size_t probe2 = (hashValue * 37) % pces.size();
if (pces[probe2].Retrieve(styleNumber, sv, positions)) {
if (pces[probe2].Retrieve(styleNumber, unicode, sv, positions)) {
return;
}
// Not found. Choose the oldest of the two slots to replace
@ -989,7 +1057,11 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns
}
const Font *fontStyle = style.font.get();
surface->MeasureWidths(fontStyle, sv, positions);
if (unicode) {
surface->MeasureWidthsUTF8(fontStyle, sv, positions);
} else {
surface->MeasureWidths(fontStyle, sv, positions);
}
if (probe < pces.size()) {
// Store into cache
std::unique_lock<std::mutex> guard(mutex, std::defer_lock);
@ -1006,7 +1078,7 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns
clock = 2;
}
allClear = false;
pces[probe].Set(styleNumber, sv, positions, clock);
pces[probe].Set(styleNumber, unicode, sv, positions, clock);
}
}

View File

@ -48,7 +48,6 @@ public:
*/
class LineLayout {
private:
friend class LineLayoutCache;
std::unique_ptr<int []>lineStarts;
int lenLineStarts;
/// Drawing is only performed for @a maxLineLength characters on each line.
@ -105,7 +104,10 @@ public:
int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const noexcept;
Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const noexcept;
XYPOSITION XInLine(Sci::Position index) const noexcept;
Interval Span(int start, int end) const noexcept;
Interval SpanByte(int index) const noexcept;
int EndLineStyle() const noexcept;
void WrapLine(const Document *pdoc, Sci::Position posLineStart, Wrap wrapState);
};
struct ScreenLine : public IScreenLine {
@ -255,7 +257,7 @@ public:
virtual void SetSize(size_t size_) = 0;
virtual size_t GetSize() const noexcept = 0;
virtual void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
std::string_view sv, XYPOSITION *positions, bool needsLocking) = 0;
bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) = 0;
};
std::unique_ptr<IPositionCache> CreatePositionCache();

View File

@ -78,11 +78,12 @@ void ScintillaBase::Finalise() {
}
void ScintillaBase::InsertCharacter(std::string_view sv, CharacterSource charSource) {
const bool isFillUp = ac.Active() && ac.IsFillUpChar(sv[0]);
const bool acActive = ac.Active();
const bool isFillUp = acActive && ac.IsFillUpChar(sv[0]);
if (!isFillUp) {
Editor::InsertCharacter(sv, charSource);
}
if (ac.Active()) {
if (acActive) {
AutoCompleteCharacterAdded(sv[0]);
// For fill ups add the character after the autocompletion has
// triggered so containers see the key so can display a calltip.

View File

@ -81,6 +81,12 @@ struct SelectionSegment {
if (end < p)
end = p;
}
SelectionSegment Subtract(Sci::Position increment) const noexcept {
SelectionSegment ret(start, end);
ret.start.Add(-increment);
ret.end.Add(-increment);
return ret;
}
};
struct SelectionRange {

View File

@ -530,8 +530,8 @@ bool ViewStyle::IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) cons
// display itself (as long as it's not an MarkerSymbol::Empty marker). These are checked in order
// with the earlier taking precedence. When multiple markers cause background override,
// the colour for the highest numbered one is used.
std::optional<ColourRGBA> ViewStyle::Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const {
std::optional<ColourRGBA> background;
ColourOptional ViewStyle::Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const {
ColourOptional background;
if (!caretLine.frame && (caretActive || caretLine.alwaysShow) &&
(caretLine.layer == Layer::Base) && lineContainsCaret) {
background = ElementColour(Element::CaretLineBack);
@ -601,7 +601,7 @@ void ViewStyle::AddMultiEdge(int column, ColourRGBA colour) {
EdgeProperties(column, colour));
}
std::optional<ColourRGBA> ViewStyle::ElementColour(Element element) const {
ColourOptional ViewStyle::ElementColour(Element element) const {
ElementMap::const_iterator search = elementColours.find(element);
if (search != elementColours.end()) {
if (search->second.has_value()) {
@ -617,6 +617,15 @@ std::optional<ColourRGBA> ViewStyle::ElementColour(Element element) const {
return {};
}
ColourRGBA ViewStyle::ElementColourForced(Element element) const {
// Like ElementColour but never returns empty - when not found return opaque black.
// This method avoids warnings for unwrapping potentially empty optionals from
// Visual C++ Code Analysis
const ColourOptional colour = ElementColour(element);
constexpr ColourRGBA opaqueBlack(0, 0, 0, 0xff);
return colour.value_or(opaqueBlack);
}
bool ViewStyle::ElementAllowsTranslucent(Element element) const {
return elementAllowsTranslucent.count(element) > 0;
}

View File

@ -37,7 +37,9 @@ public:
typedef std::map<FontSpecification, std::unique_ptr<FontRealised>> FontMap;
inline std::optional<ColourRGBA> OptionalColour(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) {
using ColourOptional = std::optional<ColourRGBA>;
inline ColourOptional OptionalColour(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) noexcept {
if (wParam) {
return ColourRGBA::FromIpRGB(lParam);
} else {
@ -133,8 +135,8 @@ public:
XYPOSITION controlCharWidth;
ColourRGBA selbar;
ColourRGBA selbarlight;
std::optional<ColourRGBA> foldmarginColour;
std::optional<ColourRGBA> foldmarginHighlightColour;
ColourOptional foldmarginColour;
ColourOptional foldmarginHighlightColour;
bool hotspotUnderline;
/// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin
int leftMarginWidth; ///< Spacing margin on left of text
@ -178,7 +180,7 @@ public:
int ctrlCharPadding; // the padding around control character text blobs
int lastSegItalicsOffset; // the offset so as not to clip italic characters at EOLs
using ElementMap = std::map<Scintilla::Element, std::optional<ColourRGBA>>;
using ElementMap = std::map<Scintilla::Element, ColourOptional>;
ElementMap elementColours;
ElementMap elementBaseColours;
std::set<Scintilla::Element> elementAllowsTranslucent;
@ -210,7 +212,7 @@ public:
void CalcLargestMarkerHeight() noexcept;
int GetFrameWidth() const noexcept;
bool IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const;
std::optional<ColourRGBA> Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const;
ColourOptional Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const;
bool SelectionBackgroundDrawn() const noexcept;
bool SelectionTextDrawn() const;
bool WhitespaceBackgroundDrawn() const;
@ -218,7 +220,8 @@ public:
void AddMultiEdge(int column, ColourRGBA colour);
std::optional<ColourRGBA> ElementColour(Scintilla::Element element) const;
ColourOptional ElementColour(Scintilla::Element element) const;
ColourRGBA ElementColourForced(Scintilla::Element element) const;
bool ElementAllowsTranslucent(Scintilla::Element element) const;
bool ResetElement(Scintilla::Element element);
bool SetElementColour(Scintilla::Element element, ColourRGBA colour);

View File

@ -239,6 +239,14 @@ RGBAImage::RGBAImage(const XPM &xpm) {
}
}
float RGBAImage::GetScaledHeight() const noexcept {
return static_cast<float>(height) / scale;
}
float RGBAImage::GetScaledWidth() const noexcept {
return static_cast<float>(width) / scale;
}
int RGBAImage::CountBytes() const noexcept {
return width * height * 4;
}
@ -256,15 +264,23 @@ void RGBAImage::SetPixel(int x, int y, ColourRGBA colour) noexcept {
pixel[3] = colour.GetAlpha();
}
namespace {
unsigned char AlphaMultiplied(unsigned char value, unsigned char alpha) {
return (value * alpha / UCHAR_MAX) & 0xffU;
}
}
// Transform a block of pixels from RGBA to BGRA with premultiplied alpha.
// Used for DrawRGBAImage on some platforms.
void RGBAImage::BGRAFromRGBA(unsigned char *pixelsBGRA, const unsigned char *pixelsRGBA, size_t count) noexcept {
for (size_t i = 0; i < count; i++) {
const unsigned char alpha = pixelsRGBA[3];
// Input is RGBA, output is BGRA with premultiplied alpha
pixelsBGRA[2] = pixelsRGBA[0] * alpha / UCHAR_MAX;
pixelsBGRA[1] = pixelsRGBA[1] * alpha / UCHAR_MAX;
pixelsBGRA[0] = pixelsRGBA[2] * alpha / UCHAR_MAX;
pixelsBGRA[2] = AlphaMultiplied(pixelsRGBA[0], alpha);
pixelsBGRA[1] = AlphaMultiplied(pixelsRGBA[1], alpha);
pixelsBGRA[0] = AlphaMultiplied(pixelsRGBA[2], alpha);
pixelsBGRA[3] = alpha;
pixelsRGBA += bytesPerPixel;
pixelsBGRA += bytesPerPixel;

Some files were not shown because too many files have changed in this diff Show More