Menu

#1467 Creating a Docpointer without a Scintilla window

Initial
open
nobody
None
5
2023-12-25
2022-11-29
Iain Clarke
No

Actual request:
Export a function like:
Scintilla::IDocument * dllexport CreateDocument ();
from Scintilla DLL.
And base the Internal::Document class on a limited public interface so we can operate on a document with no views.

Scintilla_DirectFunction gives precedent to direct functions existing.

Background:
We've been using Scintilla for many years now, and recently I was having a clean up of our codebase. One thing that is strange, is that we have a doc/view model (MFC initally, but we cannot load the text into the document until the view is created. This is clunky, but we can work around it.

But we have a command line tool that needs all the scintilla wrapper classes linked into it in order to load our text as well.

We can create a Document once we have a ScintillaWnd, but not before. We can't create it independently.

(Think of it like the C++ code editor for your favourite IDE)

Discussion

  • Neil Hodgson

    Neil Hodgson - 2022-11-29

    What goes into the 'limited public interface'? It has to be a subset that is likely to be viable for a lengthy period. Include too many methods and it starts to constrain the development of Document. There are around 200 public methods in Document.

    Since C++ ABIs can differ between compilers (and even between release and debug mode), C++ classes, including standard library classes, can't be used in an interface between executable and DLL. This is similar to IDocument which is passed to lexers which are commonly in another DLL/so.

    IDocument is meant for lexers so contains no document text changing methods. ILoader is a limited preparatory view on a Document just for loading.

    The stability of IDocument can get in the way of changes: Document::StyleAtNoExcept exists just because IDocument::StyleAt can't have noexcept added until the next major version and its limited compatibility break. Having a specified calling convention SCI_METHOD == __stdcall for IDocument may also obstruct optimizations.

     
    • Iain Clarke

      Iain Clarke - 2022-12-16

      Weird I didn't see notifications for this! Sorry for my delay. (That's me issue, not you, just explaining my lack of followup).

      Yes, you do raise good points. For my own purposes, I'd just need the ability to load / access text. Accessing text is already needed by lexers, so really only adding a SetText method would do for me. But I understand that brings in the need for a lot more, like enabling undo history etc.

      The altenative I thought of was to create a zero sized invisible window, configure it, load into it, detach the IDocument then destroy the window, giving me what I wanted - but it seems rather clunky.

       
  • Neil Hodgson

    Neil Hodgson - 2022-12-18

    but we cannot load the text into the document until the view is created

    If you have a view, you can create an ILoader that is initially independent of any view while loading and which can then be moved into a view.

    create a zero sized invisible window, configure it, load into it, detach the IDocument then destroy the window

    A Message-Only Window may work here but I've never tried it.

    Another issue with having view-independent documents is that encoding-sensitive features, like case-independent searching, are implemented with platform-specific character-set translation provided by view objects.

    Here's my attempt at a limited editable document interface:

    struct SplitAccess {
        const char *segment1;
        size_t length1;
        const char *segment2;
        size_t length;
    };
    
    class IEditableDocument {
    public:
        virtual int SCI_METHOD Version() const = 0;
        virtual int SCI_METHOD Release() = 0;
    
        virtual Sci_Position SCI_METHOD Length() const = 0;
        virtual void SCI_METHOD GetCharRange(char *buffer, Sci_Position position, Sci_Position lengthRetrieve) const = 0;
        virtual int SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const = 0;
    
        virtual Sci_Position SCI_METHOD LineFromPosition(Sci_Position position) const = 0;
        virtual Sci_Position SCI_METHOD LineStart(Sci_Position line) const = 0;
    
        // For direct read access, building something like SplitView
        virtual void SCI_METHOD SplitData(SplitAccess *split) const = 0;
    
        // Modifying
        virtual bool SCI_METHOD DeleteText(Sci::Position pos, Sci::Position len) = 0;
        virtual Sci::Position SCI_METHOD InsertText(Sci::Position position, const char *s, Sci::Position insertLength) = 0;
    };
    
     
  • Neil Hodgson

    Neil Hodgson - 2023-12-25

    Implemented a simple initial provisional implementation of IEditableDocument with just DEVersion, AddRef, and Release methods as [2af035]. Still needs a view to call SCI_CREATEDOCUMENT or similar on.

     

    Related

    Commit: [2af035]


Log in to post a comment.

MongoDB Logo MongoDB