aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/ScintillaDoc.html61
-rw-r--r--doc/ScintillaHistory.html4
-rw-r--r--gtk/ScintillaGTK.cxx5
-rw-r--r--include/Scintilla.h4
-rw-r--r--include/Scintilla.iface6
-rw-r--r--src/Document.cxx113
-rw-r--r--src/Document.h12
-rw-r--r--src/Editor.cxx194
-rw-r--r--src/ScintillaBase.cxx4
-rw-r--r--win32/ScintillaWin.cxx8
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);