diff options
-rw-r--r-- | doc/ScintillaDoc.html | 61 | ||||
-rw-r--r-- | doc/ScintillaHistory.html | 4 | ||||
-rw-r--r-- | gtk/ScintillaGTK.cxx | 5 | ||||
-rw-r--r-- | include/Scintilla.h | 4 | ||||
-rw-r--r-- | include/Scintilla.iface | 6 | ||||
-rw-r--r-- | src/Document.cxx | 113 | ||||
-rw-r--r-- | src/Document.h | 12 | ||||
-rw-r--r-- | src/Editor.cxx | 194 | ||||
-rw-r--r-- | src/ScintillaBase.cxx | 4 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 8 |
10 files changed, 237 insertions, 174 deletions
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index e70b86ca0..b8789801f 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -82,7 +82,7 @@ <h1>Scintilla Documentation</h1> - <p>Last edited 08 April 2014 NH</p> + <p>Last edited 16 April 2014 NH</p> <p>There is <a class="jump" href="Design.html">an overview of the internal design of Scintilla</a>.<br /> @@ -413,6 +413,7 @@ <a class="message" href="#SCI_ADDSTYLEDTEXT">SCI_ADDSTYLEDTEXT(int length, cell *s)</a><br /> <a class="message" href="#SCI_APPENDTEXT">SCI_APPENDTEXT(int length, const char *s)</a><br /> <a class="message" href="#SCI_INSERTTEXT">SCI_INSERTTEXT(int pos, const char *text)</a><br /> + <a class="message" href="#SCI_CHANGEINSERTION">SCI_CHANGEINSERTION(int length, const char *text)</a><br /> <a class="message" href="#SCI_CLEARALL">SCI_CLEARALL</a><br /> <a class="message" href="#SCI_DELETERANGE">SCI_DELETERANGE(int pos, int deleteLength)</a><br /> <a class="message" href="#SCI_CLEARDOCUMENTSTYLE">SCI_CLEARDOCUMENTSTYLE</a><br /> @@ -546,6 +547,10 @@ the current position if <code>pos</code> is -1. If the current position is after the insertion point then it is moved along with its surrounding text but no scrolling is performed.</p> + <p><b id="SCI_CHANGEINSERTION">SCI_CHANGEINSERTION(int length, const char *text)</b><br /> + This may only be called from a <a class="message" href="#SC_MOD_INSERTCHECK">SC_MOD_INSERTCHECK</a> + notification handler and will change the text being inserted to that provided.</p> + <p><b id="SCI_CLEARALL">SCI_CLEARALL</b><br /> Unless the document is read-only, this deletes all the text.</p> @@ -6791,7 +6796,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MOD_INSERTTEXT</code></td> - <td align="center">0x01</td> + <td align="right">0x01</td> <td>Text has been inserted into the document.</td> @@ -6801,7 +6806,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MOD_DELETETEXT</code></td> - <td align="center">0x02</td> + <td align="right">0x02</td> <td>Text has been removed from the document.</td> @@ -6811,7 +6816,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MOD_CHANGESTYLE</code></td> - <td align="center">0x04</td> + <td align="right">0x04</td> <td>A style change has occurred.</td> @@ -6821,7 +6826,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MOD_CHANGEFOLD</code></td> - <td align="center">0x08</td> + <td align="right">0x08</td> <td>A folding change has occurred.</td> @@ -6831,7 +6836,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_PERFORMED_USER</code></td> - <td align="center">0x10</td> + <td align="right">0x10</td> <td>Information: the operation was done by the user.</td> @@ -6841,7 +6846,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_PERFORMED_UNDO</code></td> - <td align="center">0x20</td> + <td align="right">0x20</td> <td>Information: this was the result of an Undo.</td> @@ -6851,7 +6856,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_PERFORMED_REDO</code></td> - <td align="center">0x40</td> + <td align="right">0x40</td> <td>Information: this was the result of a Redo.</td> @@ -6861,7 +6866,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MULTISTEPUNDOREDO</code></td> - <td align="center">0x80</td> + <td align="right">0x80</td> <td>This is part of a multi-step Undo or Redo transaction.</td> @@ -6871,7 +6876,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_LASTSTEPINUNDOREDO</code></td> - <td align="center">0x100</td> + <td align="right">0x100</td> <td>This is the final step in an Undo or Redo transaction.</td> @@ -6881,7 +6886,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MOD_CHANGEMARKER</code></td> - <td align="center">0x200</td> + <td align="right">0x200</td> <td>One or more markers has changed in a line.</td> @@ -6891,7 +6896,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MOD_BEFOREINSERT</code></td> - <td align="center">0x400</td> + <td align="right">0x400</td> <td>Text is about to be inserted into the document.</td> @@ -6901,7 +6906,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MOD_BEFOREDELETE</code></td> - <td align="center">0x800</td> + <td align="right">0x800</td> <td>Text is about to be deleted from the document.</td> @@ -6911,7 +6916,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MOD_CHANGEINDICATOR</code></td> - <td align="center">0x4000</td> + <td align="right">0x4000</td> <td>An indicator has been added or removed from a range of text.</td> @@ -6921,7 +6926,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code id="SC_MOD_CHANGELINESTATE">SC_MOD_CHANGELINESTATE</code></td> - <td align="center">0x8000</td> + <td align="right">0x8000</td> <td>A line state has changed because <a class="message" href="#SCI_SETLINESTATE">SCI_SETLINESTATE</a> was called.</td> @@ -6932,7 +6937,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code id="SC_MOD_LEXERSTATE">SC_MOD_LEXERSTATE</code></td> - <td align="center">0x80000</td> + <td align="right">0x80000</td> <td>The internal state of a lexer has changed over a range.</td> @@ -6942,7 +6947,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code id="SC_MOD_CHANGEMARGIN">SC_MOD_CHANGEMARGIN</code></td> - <td align="center">0x10000</td> + <td align="right">0x10000</td> <td>A text margin has changed.</td> @@ -6952,7 +6957,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code id="SC_MOD_CHANGEANNOTATION">SC_MOD_CHANGEANNOTATION</code></td> - <td align="center">0x20000</td> + <td align="right">0x20000</td> <td>An annotation has changed.</td> @@ -6960,9 +6965,21 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); </tr> <tr> + <td align="left"><code id="SC_MOD_INSERTCHECK">SC_MOD_INSERTCHECK</code></td> + + <td align="right">0x100000</td> + + <td>Text is about to be inserted. The handler may change the text being inserted by calling + <a class="message" href="#SCI_CHANGEINSERTION">SCI_CHANGEINSERTION</a>. + No other modifications may be made in this handler.</td> + + <td><code>position, length, text</code></td> + </tr> + + <tr> <td align="left"><code>SC_MULTILINEUNDOREDO</code></td> - <td align="center">0x1000</td> + <td align="right">0x1000</td> <td>This is part of an Undo or Redo with multi-line changes.</td> @@ -6972,7 +6989,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_STARTACTION</code></td> - <td align="center">0x2000</td> + <td align="right">0x2000</td> <td>This is set on a SC_PERFORMED_USER action when it is the first or only step in an undo transaction. This can be used to integrate the Scintilla @@ -6987,7 +7004,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code id="SC_MOD_CONTAINER">SC_MOD_CONTAINER</code></td> - <td align="center">0x40000</td> + <td align="right">0x40000</td> <td>This is set on for actions that the container stored into the undo stack with <a class="message" href="#SCI_ADDUNDOACTION"><code>SCI_ADDUNDOACTION</code></a>. @@ -6999,7 +7016,7 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); <tr> <td align="left"><code>SC_MODEVENTMASKALL</code></td> - <td align="center">0x7FFFF</td> + <td align="right">0x1FFFFF</td> <td>This is a mask for all valid flags. This is the default mask state set by <a class="message" href="#SCI_SETMODEVENTMASK"><code>SCI_SETMODEVENTMASK</code></a>.</td> diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 7777e5bfa..7b762a1b9 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -466,6 +466,10 @@ Released 1 April 2014. </li> <li> + Insertions can be filtered or modified by calling SCI_CHANGEINSERTION inside a handler for + SC_MOD_INSERTCHECK. + </li> + <li> C++ lexer can highlight task marker keywords in comments as SCE_C_TASKMARKER. </li> <li> diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index ee0758bcd..2c51d1d0e 100644 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -2168,8 +2168,9 @@ gboolean ScintillaGTK::KeyThis(GdkEventKey *event) { //fprintf(stderr, "SK-key: %d %x %x\n",event->keyval, event->state, consumed); if (event->keyval == 0xffffff && event->length > 0) { ClearSelection(); - if (pdoc->InsertCString(CurrentPosition(), event->string)) { - MovePositionTo(CurrentPosition() + event->length); + const int lengthInserted = pdoc->InsertString(CurrentPosition(), event->string, strlen(event->string)); + if (lengthInserted > 0) { + MovePositionTo(CurrentPosition() + lengthInserted); } } return consumed; diff --git a/include/Scintilla.h b/include/Scintilla.h index 462f5b5c3..ea2c12bc1 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -50,6 +50,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_ADDTEXT 2001 #define SCI_ADDSTYLEDTEXT 2002 #define SCI_INSERTTEXT 2003 +#define SCI_CHANGEINSERTION 2672 #define SCI_CLEARALL 2004 #define SCI_DELETERANGE 2645 #define SCI_CLEARDOCUMENTSTYLE 2005 @@ -945,7 +946,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_MOD_CHANGEANNOTATION 0x20000 #define SC_MOD_CONTAINER 0x40000 #define SC_MOD_LEXERSTATE 0x80000 -#define SC_MODEVENTMASKALL 0xFFFFF +#define SC_MOD_INSERTCHECK 0x100000 +#define SC_MODEVENTMASKALL 0x1FFFFF #define SC_UPDATE_CONTENT 0x1 #define SC_UPDATE_SELECTION 0x2 #define SC_UPDATE_V_SCROLL 0x4 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 02cb97193..e5167902c 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -98,6 +98,9 @@ fun void AddStyledText=2002(int length, cells c) # Insert string at a position. fun void InsertText=2003(position pos, string text) +# Change the text that is being inserted in response to SC_MOD_INSERTCHECK +fun void ChangeInsertion=2672(int length, string text) + # Delete all text in the document. fun void ClearAll=2004(,) @@ -2494,7 +2497,8 @@ val SC_MOD_CHANGEMARGIN=0x10000 val SC_MOD_CHANGEANNOTATION=0x20000 val SC_MOD_CONTAINER=0x40000 val SC_MOD_LEXERSTATE=0x80000 -val SC_MODEVENTMASKALL=0xFFFFF +val SC_MOD_INSERTCHECK=0x100000 +val SC_MODEVENTMASKALL=0x1FFFFF enu Update=SC_UPDATE_ val SC_UPDATE_CONTENT=0x1 diff --git a/src/Document.cxx b/src/Document.cxx index 1788cf74e..0108669c2 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -98,6 +98,7 @@ Document::Document() { enteredModification = 0; enteredStyling = 0; enteredReadOnlyCount = 0; + insertionSet = false; tabInChars = 8; indentInChars = 0; actualIndentInChars = 8; @@ -919,37 +920,56 @@ bool Document::DeleteChars(int pos, int len) { /** * Insert a string with a length. */ -bool Document::InsertString(int position, const char *s, int insertLength) { +int Document::InsertString(int position, const char *s, int insertLength) { if (insertLength <= 0) { - return false; + return 0; + } + CheckReadOnly(); // Application may change read only state here + if (cb.IsReadOnly()) { + return 0; } - CheckReadOnly(); if (enteredModification != 0) { - return false; - } else { - enteredModification++; - if (!cb.IsReadOnly()) { - NotifyModified( - DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_USER, - position, insertLength, - 0, s)); - int prevLinesTotal = LinesTotal(); - bool startSavePoint = cb.IsSavePoint(); - bool startSequence = false; - const char *text = cb.InsertString(position, s, insertLength, startSequence); - if (startSavePoint && cb.IsCollectingUndo()) - NotifySavePoint(!startSavePoint); - ModifiedAt(position); - NotifyModified( - DocModification( - SC_MOD_INSERTTEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), - position, insertLength, - LinesTotal() - prevLinesTotal, text)); - } - enteredModification--; + return 0; } - return !cb.IsReadOnly(); + enteredModification++; + insertionSet = false; + insertion.clear(); + NotifyModified( + DocModification( + SC_MOD_INSERTCHECK, + position, insertLength, + 0, s)); + if (insertionSet) { + s = insertion.c_str(); + insertLength = static_cast<int>(insertion.length()); + } + NotifyModified( + DocModification( + SC_MOD_BEFOREINSERT | SC_PERFORMED_USER, + position, insertLength, + 0, s)); + int prevLinesTotal = LinesTotal(); + bool startSavePoint = cb.IsSavePoint(); + bool startSequence = false; + const char *text = cb.InsertString(position, s, insertLength, startSequence); + if (startSavePoint && cb.IsCollectingUndo()) + NotifySavePoint(!startSavePoint); + ModifiedAt(position); + NotifyModified( + DocModification( + SC_MOD_INSERTTEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), + position, insertLength, + LinesTotal() - prevLinesTotal, text)); + if (insertionSet) { // Free memory as could be large + std::string().swap(insertion); + } + enteredModification--; + return insertLength; +} + +void Document::ChangeInsertion(const char *s, int length) { + insertionSet = true; + insertion.assign(s, length); } int SCI_METHOD Document::AddData(char *data, int length) { @@ -1113,22 +1133,6 @@ int Document::Redo() { return newPos; } -/** - * Insert a single character. - */ -bool Document::InsertChar(int pos, char ch) { - char chs[1]; - chs[0] = ch; - return InsertString(pos, chs, 1); -} - -/** - * Insert a null terminated string. - */ -bool Document::InsertCString(int position, const char *s) { - return InsertString(position, s, static_cast<int>(s ? strlen(s) : 0)); -} - void Document::DelChar(int pos) { DeleteChars(pos, LenChar(pos)); } @@ -1183,7 +1187,7 @@ int SCI_METHOD Document::GetLineIndentation(int line) { return indent; } -void Document::SetLineIndentation(int line, int indent) { +int Document::SetLineIndentation(int line, int indent) { int indentOfLine = GetLineIndentation(line); if (indent < 0) indent = 0; @@ -1193,7 +1197,10 @@ void Document::SetLineIndentation(int line, int indent) { int indentPos = GetLineIndentPosition(line); UndoGroup ug(this); DeleteChars(thisLineStart, indentPos - thisLineStart); - InsertCString(thisLineStart, linebuf.c_str()); + return thisLineStart + InsertString(thisLineStart, linebuf.c_str(), + static_cast<int>(linebuf.length())); + } else { + return GetLineIndentPosition(line); } } @@ -1325,21 +1332,21 @@ void Document::ConvertLineEnds(int eolModeSet) { } else { // CR if (eolModeSet == SC_EOL_CRLF) { - InsertString(pos + 1, "\n", 1); // Insert LF - pos++; + pos += InsertString(pos + 1, "\n", 1); // Insert LF } else if (eolModeSet == SC_EOL_LF) { - InsertString(pos, "\n", 1); // Insert LF - DeleteChars(pos + 1, 1); // Delete CR + pos += InsertString(pos, "\n", 1); // Insert LF + DeleteChars(pos, 1); // Delete CR + pos--; } } } else if (cb.CharAt(pos) == '\n') { // LF if (eolModeSet == SC_EOL_CRLF) { - InsertString(pos, "\r", 1); // Insert CR - pos++; + pos += InsertString(pos, "\r", 1); // Insert CR } else if (eolModeSet == SC_EOL_CR) { - InsertString(pos, "\r", 1); // Insert CR - DeleteChars(pos + 1, 1); // Delete LF + pos += InsertString(pos, "\r", 1); // Insert CR + DeleteChars(pos, 1); // Delete LF + pos--; } } } diff --git a/src/Document.h b/src/Document.h index effdd5fe5..d73715764 100644 --- a/src/Document.h +++ b/src/Document.h @@ -205,6 +205,9 @@ private: int enteredStyling; int enteredReadOnlyCount; + bool insertionSet; + std::string insertion; + std::vector<WatcherWithUserData> watchers; // ldSize is not real data - it is for dimensions and loops @@ -274,7 +277,8 @@ public: void ModifiedAt(int pos); void CheckReadOnly(); bool DeleteChars(int pos, int len); - bool InsertString(int position, const char *s, int insertLength); + int InsertString(int position, const char *s, int insertLength); + void ChangeInsertion(const char *s, int length); int SCI_METHOD AddData(char *data, int length); void * SCI_METHOD ConvertToDocument(); int Undo(); @@ -296,7 +300,7 @@ public: int GapPosition() const { return cb.GapPosition(); } int SCI_METHOD GetLineIndentation(int line); - void SetLineIndentation(int line, int indent); + int SetLineIndentation(int line, int indent); int GetLineIndentPosition(int line) const; int GetColumn(int position); int CountCharacters(int startPos, int endPos); @@ -307,8 +311,6 @@ public: void SetReadOnly(bool set) { cb.SetReadOnly(set); } bool IsReadOnly() const { return cb.IsReadOnly(); } - bool InsertChar(int pos, char ch); - bool InsertCString(int position, const char *s); void DelChar(int pos); void DelCharBack(int pos); @@ -390,7 +392,7 @@ public: void AnnotationSetStyles(int line, const unsigned char *styles); int AnnotationLines(int line) const; void AnnotationClearAll(); - + bool AddWatcher(DocWatcher *watcher, void *userData); bool RemoveWatcher(DocWatcher *watcher, void *userData); diff --git a/src/Editor.cxx b/src/Editor.cxx index 6cb33a07a..aaa440dce 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -1096,7 +1096,7 @@ void Editor::VerticalCentreCaret() { // Avoid 64 bit compiler warnings. // Scintilla does not support text buffers larger than 2**31 static int istrlen(const char *s) { - return static_cast<int>(strlen(s)); + return static_cast<int>(s ? strlen(s) : 0); } void Editor::MoveSelectedLines(int lineDelta) { @@ -1150,13 +1150,13 @@ void Editor::MoveSelectedLines(int lineDelta) { const char *eol = StringFromEOLMode(pdoc->eolMode); if (currentLine + lineDelta >= pdoc->LinesTotal()) - pdoc->InsertCString(pdoc->Length(), eol); + pdoc->InsertString(pdoc->Length(), eol, istrlen(eol)); GoToLine(currentLine + lineDelta); - pdoc->InsertCString(CurrentPosition(), selectedText.Data()); + selectionLength = pdoc->InsertString(CurrentPosition(), selectedText.Data(), selectionLength); if (appendEol) { - pdoc->InsertCString(CurrentPosition() + selectionLength, eol); - selectionLength += istrlen(eol); + const int lengthInserted = pdoc->InsertString(CurrentPosition() + selectionLength, eol, istrlen(eol)); + selectionLength += lengthInserted; } SetSelection(CurrentPosition(), CurrentPosition() + selectionLength); } @@ -1694,8 +1694,8 @@ void Editor::LinesJoin() { pdoc->DelChar(pos); if (prevNonWS) { // Ensure at least one space separating previous lines - pdoc->InsertChar(pos, ' '); - targetEnd++; + const int lengthInserted = pdoc->InsertString(pos, " ", 1); + targetEnd += lengthInserted; } } else { prevNonWS = pdoc->CharAt(pos) != ' '; @@ -1730,12 +1730,14 @@ void Editor::LinesSplit(int pixelWidth) { if (surface && ll) { unsigned int posLineStart = pdoc->LineStart(line); LayoutLine(line, surface, vs, ll, pixelWidth); + int lengthInsertedTotal = 0; for (int subLine = 1; subLine < ll->lines; subLine++) { - pdoc->InsertCString( - static_cast<int>(posLineStart + (subLine - 1) * strlen(eol) + + const int lengthInserted = pdoc->InsertString( + static_cast<int>(posLineStart + lengthInsertedTotal + ll->LineStart(subLine)), - eol); - targetEnd += static_cast<int>(strlen(eol)); + eol, istrlen(eol)); + targetEnd += lengthInserted; + lengthInsertedTotal += lengthInserted; } } lineEnd = pdoc->LineFromPosition(targetEnd); @@ -4017,8 +4019,8 @@ void Editor::ChangeSize() { int Editor::InsertSpace(int position, unsigned int spaces) { if (spaces > 0) { std::string spaceText(spaces, ' '); - pdoc->InsertString(position, spaceText.c_str(), spaces); - position += spaces; + const int lengthInserted = pdoc->InsertString(position, spaceText.c_str(), spaces); + position += lengthInserted; } return position; } @@ -4077,9 +4079,10 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) { } } positionInsert = InsertSpace(positionInsert, currentSel->caret.VirtualSpace()); - if (pdoc->InsertString(positionInsert, s, len)) { - currentSel->caret.SetPosition(positionInsert + len); - currentSel->anchor.SetPosition(positionInsert + len); + const int lengthInserted = pdoc->InsertString(positionInsert, s, len); + if (lengthInserted > 0) { + currentSel->caret.SetPosition(positionInsert + lengthInserted); + currentSel->anchor.SetPosition(positionInsert + lengthInserted); } currentSel->ClearVirtualSpace(); // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information @@ -4154,8 +4157,9 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) { void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len) { if (multiPasteMode == SC_MULTIPASTE_ONCE) { selStart = SelectionPosition(InsertSpace(selStart.Position(), selStart.VirtualSpace())); - if (pdoc->InsertString(selStart.Position(), text, len)) { - SetEmptySelection(selStart.Position() + len); + const int lengthInserted = pdoc->InsertString(selStart.Position(), text, len); + if (lengthInserted > 0) { + SetEmptySelection(selStart.Position() + lengthInserted); } } else { // SC_MULTIPASTE_EACH @@ -4173,9 +4177,10 @@ void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len) } } positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace()); - if (pdoc->InsertString(positionInsert, text, len)) { - sel.Range(r).caret.SetPosition(positionInsert + len); - sel.Range(r).anchor.SetPosition(positionInsert + len); + const int lengthInserted = pdoc->InsertString(positionInsert, text, len); + if (lengthInserted > 0) { + sel.Range(r).caret.SetPosition(positionInsert + lengthInserted); + sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted); } sel.Range(r).ClearVirtualSpace(); } @@ -4271,22 +4276,22 @@ void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, int len) { line++; if (line >= pdoc->LinesTotal()) { if (pdoc->eolMode != SC_EOL_LF) - pdoc->InsertChar(pdoc->Length(), '\r'); + pdoc->InsertString(pdoc->Length(), "\r", 1); if (pdoc->eolMode != SC_EOL_CR) - pdoc->InsertChar(pdoc->Length(), '\n'); + pdoc->InsertString(pdoc->Length(), "\n", 1); } // Pad the end of lines with spaces if required sel.RangeMain().caret.SetPosition(PositionFromLineX(line, xInsert)); if ((XFromPosition(sel.MainCaret()) < xInsert) && (i + 1 < len)) { while (XFromPosition(sel.MainCaret()) < xInsert) { - pdoc->InsertChar(sel.MainCaret(), ' '); - sel.RangeMain().caret.Add(1); + const int lengthInserted = pdoc->InsertString(sel.MainCaret(), " ", 1); + sel.RangeMain().caret.Add(lengthInserted); } } prevCr = ptr[i] == '\r'; } else { - pdoc->InsertString(sel.MainCaret(), ptr + i, 1); - sel.RangeMain().caret.Add(1); + const int lengthInserted = pdoc->InsertString(sel.MainCaret(), ptr + i, 1); + sel.RangeMain().caret.Add(lengthInserted); prevCr = false; } } @@ -4382,14 +4387,12 @@ void Editor::DelCharBack(bool allowLineStartDeletion) { UndoGroup ugInner(pdoc, !ug.Needed()); int indentation = pdoc->GetLineIndentation(lineCurrentPos); int indentationStep = pdoc->IndentSize(); - if (indentation % indentationStep == 0) { - pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); - } else { - pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep)); - } + int indentationChange = indentation % indentationStep; + if (indentationChange == 0) + indentationChange = indentationStep; + const int posSelect = pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationChange); // SetEmptySelection - sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos), - pdoc->GetLineIndentPosition(lineCurrentPos)); + sel.Range(r) = SelectionRange(posSelect); } else { pdoc->DelCharBack(sel.Range(r).caret.Position()); } @@ -5037,12 +5040,13 @@ void Editor::ChangeCaseOfSelection(int caseMapping) { pdoc->DeleteChars( static_cast<int>(currentNoVS.Start().Position() + firstDifference), static_cast<int>(rangeBytes - firstDifference - endDifferenceText)); - pdoc->InsertString( + const int lengthChange = static_cast<int>(lastDifferenceMapped - firstDifference + 1); + const int lengthInserted = pdoc->InsertString( static_cast<int>(currentNoVS.Start().Position() + firstDifference), sMapped.c_str() + firstDifference, - static_cast<int>(lastDifferenceMapped - firstDifference + 1)); + lengthChange); // Automatic movement changes selection so reset to exactly the same as it was. - int diffSizes = static_cast<int>(sMapped.size() - sText.size()); + int diffSizes = static_cast<int>(sMapped.size() - sText.size()) + lengthInserted - lengthChange; if (diffSizes != 0) { if (current.anchor > current.caret) current.anchor.Add(diffSizes); @@ -5059,19 +5063,23 @@ void Editor::LineTranspose() { int line = pdoc->LineFromPosition(sel.MainCaret()); if (line > 0) { UndoGroup ug(pdoc); - int startPrev = pdoc->LineStart(line - 1); - int endPrev = pdoc->LineEnd(line - 1); - int start = pdoc->LineStart(line); - int end = pdoc->LineEnd(line); - std::string line1 = RangeText(startPrev, endPrev); - int len1 = endPrev - startPrev; - std::string line2 = RangeText(start, end); - int len2 = end - start; - pdoc->DeleteChars(start, len2); - pdoc->DeleteChars(startPrev, len1); - pdoc->InsertString(startPrev, line2.c_str(), len2); - pdoc->InsertString(start - len1 + len2, line1.c_str(), len1); - MovePositionTo(SelectionPosition(start - len1 + len2)); + + const int startPrevious = pdoc->LineStart(line - 1); + const std::string linePrevious = RangeText(startPrevious, pdoc->LineEnd(line - 1)); + + int startCurrent = pdoc->LineStart(line); + const std::string lineCurrent = RangeText(startCurrent, pdoc->LineEnd(line)); + + pdoc->DeleteChars(startCurrent, static_cast<int>(lineCurrent.length())); + pdoc->DeleteChars(startPrevious, static_cast<int>(linePrevious.length())); + startCurrent -= static_cast<int>(linePrevious.length()); + + startCurrent += pdoc->InsertString(startPrevious, lineCurrent.c_str(), + static_cast<int>(lineCurrent.length())); + pdoc->InsertString(startCurrent, linePrevious.c_str(), + static_cast<int>(linePrevious.length())); + // Move caret to start of current line + MovePositionTo(SelectionPosition(startCurrent)); } } @@ -5095,9 +5103,10 @@ void Editor::Duplicate(bool forLine) { end = SelectionPosition(pdoc->LineEnd(line)); } std::string text = RangeText(start.Position(), end.Position()); + int lengthInserted = eolLen; if (forLine) - pdoc->InsertString(end.Position(), eol, eolLen); - pdoc->InsertString(end.Position() + eolLen, text.c_str(), SelectionRange(end, start).Length()); + lengthInserted = pdoc->InsertString(end.Position(), eol, eolLen); + pdoc->InsertString(end.Position() + lengthInserted, text.c_str(), static_cast<int>(text.length())); } if (sel.Count() && sel.IsRectangular()) { SelectionPosition last = sel.Last(); @@ -5136,12 +5145,12 @@ void Editor::NewLine() { } else if (pdoc->eolMode == SC_EOL_CR) { eol = "\r"; } // else SC_EOL_LF -> "\n" already set - bool inserted = pdoc->InsertCString(sel.MainCaret(), eol); + const int insertLength = pdoc->InsertString(sel.MainCaret(), eol, istrlen(eol)); // Want to end undo group before NotifyChar as applications often modify text here if (needGroupUndo) pdoc->EndUndoAction(); - if (inserted) { - SetEmptySelection(sel.MainCaret() + istrlen(eol)); + if (insertLength > 0) { + SetEmptySelection(sel.MainCaret() + insertLength); while (*eol) { NotifyChar(*eol); if (recordingMacro) { @@ -5789,21 +5798,22 @@ void Editor::Indent(bool forwards) { pdoc->tabIndents) { int indentation = pdoc->GetLineIndentation(lineCurrentPos); int indentationStep = pdoc->IndentSize(); - pdoc->SetLineIndentation(lineCurrentPos, indentation + indentationStep - indentation % indentationStep); - sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos)); + const int posSelect = pdoc->SetLineIndentation( + lineCurrentPos, indentation + indentationStep - indentation % indentationStep); + sel.Range(r) = SelectionRange(posSelect); } else { if (pdoc->useTabs) { - pdoc->InsertChar(caretPosition, '\t'); - sel.Range(r) = SelectionRange(caretPosition+1); + const int lengthInserted = pdoc->InsertString(caretPosition, "\t", 1); + sel.Range(r) = SelectionRange(caretPosition + lengthInserted); } else { int numSpaces = (pdoc->tabInChars) - (pdoc->GetColumn(caretPosition) % (pdoc->tabInChars)); if (numSpaces < 1) numSpaces = pdoc->tabInChars; - for (int i = 0; i < numSpaces; i++) { - pdoc->InsertChar(caretPosition + i, ' '); - } - sel.Range(r) = SelectionRange(caretPosition+numSpaces); + const std::string spaceText(numSpaces, ' '); + const int lengthInserted = pdoc->InsertString(caretPosition, spaceText.c_str(), + static_cast<int>(spaceText.length())); + sel.Range(r) = SelectionRange(caretPosition + lengthInserted); } } } else { @@ -5811,8 +5821,8 @@ void Editor::Indent(bool forwards) { pdoc->tabIndents) { int indentation = pdoc->GetLineIndentation(lineCurrentPos); int indentationStep = pdoc->IndentSize(); - pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); - sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos)); + const int posSelect = pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); + sel.Range(r) = SelectionRange(posSelect); } else { int newColumn = ((pdoc->GetColumn(caretPosition) - 1) / pdoc->tabInChars) * pdoc->tabInChars; @@ -6149,9 +6159,10 @@ void Editor::DropAt(SelectionPosition position, const char *value, size_t length } else { position = MovePositionOutsideChar(position, sel.MainCaret() - position.Position()); position = SelectionPosition(InsertSpace(position.Position(), position.VirtualSpace())); - if (pdoc->InsertString(position.Position(), value, static_cast<int>(lengthValue))) { + const int lengthInserted = pdoc->InsertString(position.Position(), value, static_cast<int>(lengthValue)); + if (lengthInserted > 0) { SelectionPosition posAfterInsertion = position; - posAfterInsertion.Add(static_cast<int>(lengthValue)); + posAfterInsertion.Add(lengthInserted); SetSelection(posAfterInsertion, position); } } @@ -6689,20 +6700,27 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { SelectionPosition selEnd = SelectionEnd(); if (selStart < selEnd) { if (drag.Length()) { + const int length = static_cast<int>(drag.Length()); if (ctrl) { - if (pdoc->InsertString(newPos.Position(), drag.Data(), static_cast<int>(drag.Length()))) { - SetSelection(newPos.Position(), newPos.Position() + static_cast<int>(drag.Length())); + const int lengthInserted = pdoc->InsertString( + newPos.Position(), drag.Data(), length); + if (lengthInserted > 0) { + SetSelection(newPos.Position(), newPos.Position() + lengthInserted); } } else if (newPos < selStart) { pdoc->DeleteChars(selStart.Position(), static_cast<int>(drag.Length())); - if (pdoc->InsertString(newPos.Position(), drag.Data(), static_cast<int>(drag.Length()))) { - SetSelection(newPos.Position(), newPos.Position() + static_cast<int>(drag.Length())); + const int lengthInserted = pdoc->InsertString( + newPos.Position(), drag.Data(), length); + if (lengthInserted > 0) { + SetSelection(newPos.Position(), newPos.Position() + lengthInserted); } } else if (newPos > selEnd) { pdoc->DeleteChars(selStart.Position(), static_cast<int>(drag.Length())); newPos.Add(-static_cast<int>(drag.Length())); - if (pdoc->InsertString(newPos.Position(), drag.Data(), static_cast<int>(drag.Length()))) { - SetSelection(newPos.Position(), newPos.Position() + static_cast<int>(drag.Length())); + const int lengthInserted = pdoc->InsertString( + newPos.Position(), drag.Data(), length); + if (lengthInserted > 0) { + SetSelection(newPos.Position(), newPos.Position() + lengthInserted); } } else { SetEmptySelection(newPos.Position()); @@ -7250,8 +7268,8 @@ int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) { if (targetStart != targetEnd) pdoc->DeleteChars(targetStart, targetEnd - targetStart); targetEnd = targetStart; - pdoc->InsertString(targetStart, text, length); - targetEnd = targetStart + length; + const int lengthInserted = pdoc->InsertString(targetStart, text, length); + targetEnd = targetStart + lengthInserted; return length; } @@ -7286,13 +7304,13 @@ void Editor::AddStyledText(char *buffer, int appendLength) { for (i = 0; i < textLength; i++) { text[i] = buffer[i*2]; } - pdoc->InsertString(CurrentPosition(), text.c_str(), textLength); + const int lengthInserted = pdoc->InsertString(CurrentPosition(), text.c_str(), textLength); for (i = 0; i < textLength; i++) { text[i] = buffer[i*2+1]; } pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff)); pdoc->SetStyles(textLength, text.c_str()); - SetEmptySelection(sel.MainCaret() + textLength); + SetEmptySelection(sel.MainCaret() + lengthInserted); } static bool ValidMargin(unsigned long wParam) { @@ -7447,7 +7465,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { UndoGroup ug(pdoc); pdoc->DeleteChars(0, pdoc->Length()); SetEmptySelection(0); - pdoc->InsertCString(0, CharPtrFromSPtr(lParam)); + const char *text = CharPtrFromSPtr(lParam); + pdoc->InsertString(0, text, istrlen(text)); return 1; } @@ -7605,8 +7624,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { UndoGroup ug(pdoc); ClearSelection(); char *replacement = CharPtrFromSPtr(lParam); - pdoc->InsertCString(sel.MainCaret(), replacement); - SetEmptySelection(sel.MainCaret() + istrlen(replacement)); + const int lengthInserted = pdoc->InsertString( + sel.MainCaret(), replacement, istrlen(replacement)); + SetEmptySelection(sel.MainCaret() + lengthInserted); EnsureCaretVisible(); } break; @@ -7764,8 +7784,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_ADDTEXT: { if (lParam == 0) return 0; - pdoc->InsertString(CurrentPosition(), CharPtrFromSPtr(lParam), wParam); - SetEmptySelection(sel.MainCaret() + wParam); + const int lengthInserted = pdoc->InsertString( + CurrentPosition(), CharPtrFromSPtr(lParam), wParam); + SetEmptySelection(sel.MainCaret() + lengthInserted); return 0; } @@ -7782,13 +7803,18 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { insertPos = CurrentPosition(); int newCurrent = CurrentPosition(); char *sz = CharPtrFromSPtr(lParam); - pdoc->InsertCString(insertPos, sz); + const int lengthInserted = pdoc->InsertString(insertPos, sz, istrlen(sz)); if (newCurrent > insertPos) - newCurrent += istrlen(sz); + newCurrent += lengthInserted; SetEmptySelection(newCurrent); return 0; } + case SCI_CHANGEINSERTION: + PLATFORM_ASSERT(lParam); + pdoc->ChangeInsertion(CharPtrFromSPtr(lParam), wParam); + return 0; + case SCI_APPENDTEXT: pdoc->InsertString(pdoc->Length(), CharPtrFromSPtr(lParam), wParam); return 0; diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx index dc154ec6d..e36d31389 100644 --- a/src/ScintillaBase.cxx +++ b/src/ScintillaBase.cxx @@ -198,8 +198,8 @@ void ScintillaBase::AutoCompleteDoubleClick(void *p) { void ScintillaBase::AutoCompleteInsert(Position startPos, int removeLen, const char *text, int textLen) { UndoGroup ug(pdoc); pdoc->DeleteChars(startPos, removeLen); - pdoc->InsertString(startPos, text, textLen); - SetEmptySelection(startPos + textLen); + const int lengthInserted = pdoc->InsertString(startPos, text, textLen); + SetEmptySelection(startPos + lengthInserted); } void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 10d6639e5..0e2308c70 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -1658,15 +1658,15 @@ void ScintillaWin::InsertPasteText(const char *text, int len, SelectionPosition } if (isLine) { int insertPos = pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())); - pdoc->InsertString(insertPos, text, len); + int 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); - pdoc->InsertString(insertPos + len, endline, static_cast<int>(strlen(endline))); - len += static_cast<int>(strlen(endline)); + int length = static_cast<int>(strlen(endline)); + lengthInserted += pdoc->InsertString(insertPos + lengthInserted, endline, length); } if (sel.MainCaret() == insertPos) { - SetEmptySelection(sel.MainCaret() + len); + SetEmptySelection(sel.MainCaret() + lengthInserted); } } else { InsertPaste(selStart, text, len); |