From 1b153f8d8d4b2f09afc2d039256c958e94bd3b05 Mon Sep 17 00:00:00 2001
From: Neil Last edited 5 November 2023 NH Last edited 19 December 2023 NH Scintilla 5 has moved the lexers from Scintilla into a new
Lexilla project.Scintilla Documentation
-
@@ -402,34 +402,35 @@
○ Multiple views
○ Background loading and saving
- ○ Folding
+ ○ Document interface
+
○ Folding
○ Line wrapping
○ Zooming
- ○ Long lines
+
○ Long lines
○ Accessibility
○ Lexer
- ○ Lexer objects
+
○ Lexer objects
○ Notifications
○ Images
- ○ GTK
+
○ GTK
○ Provisional messages
○ Deprecated messages
- ○ Edit messages never supported by Scintilla
+
@@ -7203,9 +7204,11 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){
windows (for use with splitter windows).○ Edit messages never supported by Scintilla
○ Removed features
○ Building Scintilla
These messages use pointer returns and arguments to refer to documents.
- They point to internal objects inside Scintilla and should be treated as an opaque void*. That
- is, you can use and store the pointer as described in this section but you should not
- dereference it.
IDocumentEditable interface is provisional and may change.
+ Client code can call IDocumentEditable methods.
+ Clients may just treat these as opaque void* values that are received from and passed to Scintilla without dereferencing.
SCI_GETDOCPOINTER → pointer
SCI_SETDOCPOINTER(<unused>, pointer doc)
SCI_CREATEDOCUMENT(position bytes, int documentOptions) → pointer
@@ -7339,7 +7342,7 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){
The documentOptions argument
is described in the SCI_CREATEDOCUMENT section.
-ILoader
+ILoader
class ILoader {
@@ -7356,7 +7359,9 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){
If a failure occurs in AddData or in a file reading call then loading can be abandoned and the loader released with
the Release call.
When the whole file has been read, ConvertToDocument should be called to produce a Scintilla
- document pointer. The newly created document will have a reference count of 1 in the same way as a document pointer
+ document pointer. This pointer can be treated as a void* cookie to pass to other APIs or cast to a
+ IDocumentEditable* pointer.
+ The newly created document will have a reference count of 1 in the same way as a document pointer
returned from
SCI_CREATEDOCUMENT.
There is no need to call Release after ConvertToDocument.
@@ -7373,6 +7378,46 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){
The application may then decide to ignore the modification or to terminate the background saving thread and reenable
modification before returning from the notification.
+ Document interface
+
+ Applications may want to manipulate documents that are not visible and the provisional IDocumentEditable
+ interface can be used for this.
+
+ IDocumentEditable allows more direct access to functionality and is faster than calling Scintilla APIs.
+
+ IDocumentEditable pointers are returned by
+ SCI_CREATEDOCUMENT,
+ SCI_GETDOCPOINTER, and
+ ILoader::ConvertToDocument.
+
+ They may be passed to
+ SCI_ADDREFDOCUMENT,
+ SCI_RELEASEDOCUMENT, and
+ SCI_SETDOCPOINTER,
+ .
+
+IDocumentEditable
+
+
+class IDocumentEditable {
+public:
+ // Allow this interface to add methods over time and discover whether new methods available.
+ virtual int SCI_METHOD DEVersion() const noexcept = 0;
+
+ // Lifetime control
+ virtual int SCI_METHOD AddRef() noexcept = 0;
+ virtual int SCI_METHOD Release() = 0;
+};
+
+
+
+ The IDocumentEditable interface is being developed and more methods will be added in the future.
+ Its also possible that methods will change signatures or be removed.
+ Thus the feature is provisional and users should be aware that they may have to modify client code in response to these changes.
+
+ DEVersion will return 0 while IDocumentEditable is provisional and will return 1
+ for the first stable release. After that, it will be incremented when new methods are added.
+
Folding
The fundamental operation in folding is making lines invisible or visible. Line visibility
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index 00023b102..a3d44d4ae 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -591,6 +591,13 @@
Released 18 November 2023.
+ Add IDocumentEditable interface to allow efficient interaction with document objects which may not be visible in
+ a Scintilla instance. This feature is provisonal and may change before being declared stable.
+ For better type-safety, the ScintillaCall C++ API uses IDocumentEditable* where void* was used before which may require
+ changes to client code that uses document pointer APIs
+ DocPointer, SetDocPointer, CreateDocument, AddRefDocument, and ReleaseDocument.
+
+
Ctrl-click on a selection deselects it in multiple selection mode.
diff --git a/include/ILoader.h b/include/ILoader.h
index 2fa69f527..5d2eb2571 100644
--- a/include/ILoader.h
+++ b/include/ILoader.h
@@ -1,6 +1,7 @@
// Scintilla source code edit control
/** @file ILoader.h
** Interface for loading into a Scintilla document from a background thread.
+ ** Interface for manipulating a document without a view.
**/
// Copyright 1998-2017 by Neil Hodgson
// The License.txt file describes the conditions under which this software may be distributed.
@@ -20,6 +21,18 @@ public:
virtual void * SCI_METHOD ConvertToDocument() = 0;
};
+static constexpr int deRelease0 = 0;
+
+class IDocumentEditable {
+public:
+ // Allow this interface to add methods over time and discover whether new methods available.
+ virtual int SCI_METHOD DEVersion() const noexcept = 0;
+
+ // Lifetime control
+ virtual int SCI_METHOD AddRef() noexcept = 0;
+ virtual int SCI_METHOD Release() = 0;
+};
+
}
#endif
diff --git a/include/ScintillaCall.h b/include/ScintillaCall.h
index 1a1a1e0f2..0ce4366d7 100644
--- a/include/ScintillaCall.h
+++ b/include/ScintillaCall.h
@@ -20,6 +20,8 @@ struct TextRangeFull;
struct TextToFindFull;
struct RangeToFormatFull;
+class IDocumentEditable;
+
using FunctionDirect = intptr_t(*)(intptr_t ptr, unsigned int iMessage, uintptr_t wParam, intptr_t lParam, int *pStatus);
struct Failure {
@@ -561,8 +563,8 @@ public:
Position BraceMatchNext(Position pos, Position startPos);
bool ViewEOL();
void SetViewEOL(bool visible);
- void *DocPointer();
- void SetDocPointer(void *doc);
+ IDocumentEditable *DocPointer();
+ void SetDocPointer(IDocumentEditable *doc);
void SetModEventMask(Scintilla::ModificationFlags eventMask);
Position EdgeColumn();
void SetEdgeColumn(Position column);
@@ -581,9 +583,9 @@ public:
bool SelectionIsRectangle();
void SetZoom(int zoomInPoints);
int Zoom();
- void *CreateDocument(Position bytes, Scintilla::DocumentOption documentOptions);
- void AddRefDocument(void *doc);
- void ReleaseDocument(void *doc);
+ IDocumentEditable *CreateDocument(Position bytes, Scintilla::DocumentOption documentOptions);
+ void AddRefDocument(IDocumentEditable *doc);
+ void ReleaseDocument(IDocumentEditable *doc);
Scintilla::DocumentOption DocumentOptions();
Scintilla::ModificationFlags ModEventMask();
void SetCommandEvents(bool commandEvents);
diff --git a/scripts/ScintillaAPIFacer.py b/scripts/ScintillaAPIFacer.py
index f26389abb..9caa1ea7f 100644
--- a/scripts/ScintillaAPIFacer.py
+++ b/scripts/ScintillaAPIFacer.py
@@ -55,7 +55,9 @@ deadValues = [
]
def ActualTypeName(type, identifier=None):
- if type in typeAliases:
+ if type == "pointer" and identifier in ["doc", "DocPointer", "CreateDocument"]:
+ return "IDocumentEditable *"
+ elif type in typeAliases:
return typeAliases[type]
else:
return type
@@ -63,6 +65,8 @@ def ActualTypeName(type, identifier=None):
def IsEnumeration(s):
if s in ["Position", "Line", "Colour", "ColourAlpha"]:
return False
+ if s.endswith("*"):
+ return False
return s[:1].isupper()
def JoinTypeAndIdentifier(type, identifier):
@@ -219,7 +223,7 @@ def HMethods(f):
if v["FeatureType"] in ["fun", "get", "set"]:
if v["FeatureType"] == "get" and name.startswith("Get"):
name = name[len("Get"):]
- retType = ActualTypeName(v["ReturnType"])
+ retType = ActualTypeName(v["ReturnType"], name)
if IsEnumeration(retType):
retType = namespace + retType
parameters, args, callName = ParametersArgsCallname(v)
@@ -241,21 +245,21 @@ def CXXMethods(f):
msgName = "Message::" + name
if v["FeatureType"] == "get" and name.startswith("Get"):
name = name[len("Get"):]
- retType = ActualTypeName(v["ReturnType"])
+ retType = ActualTypeName(v["ReturnType"], name)
parameters, args, callName = ParametersArgsCallname(v)
returnIfNeeded = "return " if retType != "void" else ""
out.append(JoinTypeAndIdentifier(retType, "ScintillaCall::" + name) + "(" + parameters + ")" + " {")
retCast = ""
retCastEnd = ""
- if retType not in basicTypes or retType in ["int", "Colour", "ColourAlpha"]:
+ if retType.endswith("*"):
+ retCast = "reinterpret_cast<" + retType + ">("
+ retCastEnd = ")"
+ elif retType not in basicTypes or retType in ["int", "Colour", "ColourAlpha"]:
if IsEnumeration(retType):
retType = namespace + retType
retCast = "static_cast<" + retType + ">("
retCastEnd = ")"
- elif retType in ["void *"]:
- retCast = "reinterpret_cast<" + retType + ">("
- retCastEnd = ")"
out.append("\t" + returnIfNeeded + retCast + callName + "(" + msgName + args + ")" + retCastEnd + ";")
out.append("}")
out.append("")
diff --git a/src/Document.cxx b/src/Document.cxx
index dcb087930..d67cac25e 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -184,7 +184,7 @@ Document::~Document() {
}
// Increase reference count and return its previous value.
-int Document::AddRef() {
+int SCI_METHOD Document::AddRef() noexcept {
return refCount++;
}
@@ -461,6 +461,10 @@ Sci_Position SCI_METHOD Document::LineEnd(Sci_Position line) const {
return cb.LineEnd(line);
}
+int SCI_METHOD Document::DEVersion() const noexcept {
+ return deRelease0;
+}
+
void SCI_METHOD Document::SetErrorStatus(int status) {
// Tell the watchers an error has occurred.
for (const WatcherWithUserData &watcher : watchers) {
@@ -1341,8 +1345,12 @@ int SCI_METHOD Document::AddData(const char *data, Sci_Position length) {
return static_cast(Status::Ok);
}
+IDocumentEditable *Document::AsDocumentEditable() noexcept {
+ return static_cast(this);
+}
+
void * SCI_METHOD Document::ConvertToDocument() {
- return this;
+ return AsDocumentEditable();
}
Sci::Position Document::Undo() {
diff --git a/src/Document.h b/src/Document.h
index f7f4eeedd..9f51fc719 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -259,7 +259,7 @@ struct CharacterExtracted {
/**
*/
-class Document : PerLine, public Scintilla::IDocument, public Scintilla::ILoader {
+class Document : PerLine, public Scintilla::IDocument, public Scintilla::ILoader, public Scintilla::IDocumentEditable {
public:
/** Used to pair watcher pointer with user data. */
@@ -329,7 +329,7 @@ public:
Document &operator=(Document &&) = delete;
~Document() override;
- int AddRef();
+ int SCI_METHOD AddRef() noexcept override;
int SCI_METHOD Release() override;
// From PerLine
@@ -347,6 +347,7 @@ public:
int SCI_METHOD Version() const override {
return Scintilla::dvRelease4;
}
+ int SCI_METHOD DEVersion() const noexcept override;
void SCI_METHOD SetErrorStatus(int status) override;
@@ -383,6 +384,7 @@ public:
Sci::Position InsertString(Sci::Position position, std::string_view sv);
void ChangeInsertion(const char *s, Sci::Position length);
int SCI_METHOD AddData(const char *data, Sci_Position length) override;
+ IDocumentEditable *AsDocumentEditable() noexcept;
void * SCI_METHOD ConvertToDocument() override;
Sci::Position Undo();
Sci::Position Redo();
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 28d680d7a..8f29d3a8f 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -6079,6 +6079,10 @@ constexpr Selection::SelTypes SelTypeFromMode(SelectionMode mode) {
}
}
+sptr_t SPtrFromPtr(void *ptr) noexcept {
+ return reinterpret_cast(ptr);
+}
+
}
void Editor::SetSelectionMode(uptr_t wParam, bool setMoveExtends) {
@@ -8216,11 +8220,11 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
break;
case Message::GetDocPointer:
- return reinterpret_cast(pdoc);
+ return SPtrFromPtr(pdoc->AsDocumentEditable());
case Message::SetDocPointer:
CancelModes();
- SetDocPointer(static_cast(PtrFromSPtr(lParam)));
+ SetDocPointer(static_cast(static_cast(PtrFromSPtr(lParam))));
return 0;
case Message::CreateDocument: {
@@ -8228,15 +8232,15 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
doc->AddRef();
doc->Allocate(PositionFromUPtr(wParam));
pcs = ContractionStateCreate(pdoc->IsLarge());
- return reinterpret_cast(doc);
+ return SPtrFromPtr(doc->AsDocumentEditable());
}
case Message::AddRefDocument:
- (static_cast(PtrFromSPtr(lParam)))->AddRef();
+ (static_cast(PtrFromSPtr(lParam)))->AddRef();
break;
case Message::ReleaseDocument:
- (static_cast(PtrFromSPtr(lParam)))->Release();
+ (static_cast(PtrFromSPtr(lParam)))->Release();
break;
case Message::GetDocumentOptions:
--
cgit v1.2.3