aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2012-05-26 15:15:07 +1000
committernyamatongwe <devnull@localhost>2012-05-26 15:15:07 +1000
commit1596a6d6b4540980cd6a8249460d881d6d190c1f (patch)
tree498aeab1fe1cf973892c069753d8d06ea5420785
parent25e91c5a5870ea1138684dbd2d67888bccce5876 (diff)
downloadscintilla-mirror-1596a6d6b4540980cd6a8249460d881d6d190c1f.tar.gz
Add GetRangePointer and GetGapPosition methods.
-rw-r--r--doc/ScintillaDoc.html20
-rw-r--r--include/Scintilla.h2
-rw-r--r--include/Scintilla.iface9
-rw-r--r--src/CellBuffer.cxx8
-rw-r--r--src/CellBuffer.h2
-rw-r--r--src/Document.h2
-rw-r--r--src/Editor.cxx6
-rw-r--r--src/SplitVector.h18
-rw-r--r--test/simpleTests.py32
9 files changed, 96 insertions, 3 deletions
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html
index 9826e769c..c610b9c70 100644
--- a/doc/ScintillaDoc.html
+++ b/doc/ScintillaDoc.html
@@ -4770,6 +4770,8 @@ struct Sci_RangeToFormat {
<code><a class="message" href="#SCI_GETDIRECTFUNCTION">SCI_GETDIRECTFUNCTION</a><br />
<a class="message" href="#SCI_GETDIRECTPOINTER">SCI_GETDIRECTPOINTER</a><br />
<a class="message" href="#SCI_GETCHARACTERPOINTER">SCI_GETCHARACTERPOINTER</a><br />
+ <a class="message" href="#SCI_GETRANGEPOINTER">SCI_GETRANGEPOINTER(int position, int rangeLength)</a><br />
+ <a class="message" href="#SCI_GETGAPPOSITION">SCI_GETGAPPOSITION</a><br />
</code>
<p>On Windows, the message-passing scheme used to communicate between the container and
@@ -4815,8 +4817,13 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){
pass in the direct pointer associated with the target window.</p>
<p><b id="SCI_GETCHARACTERPOINTER">SCI_GETCHARACTERPOINTER</b><br />
- Move the gap within Scintilla so that the text of the document is stored consecutively
- and ensure there is a NUL character after the text, then return a pointer to the first character.
+ <b id="SCI_GETRANGEPOINTER">SCI_GETRANGEPOINTER(int position, int rangeLength)</b><br />
+ <b id="SCI_GETGAPPOSITION">SCI_GETGAPPOSITION</b><br />
+ Grant temporary direct read-only access to the memory used by Scintilla to store
+ the document.</p>
+ <p><code>SCI_GETCHARACTERPOINTER</code> moves the gap within Scintilla so that the
+ text of the document is stored consecutively
+ and ensure there is a NUL character after the text, then returns a pointer to the first character.
Applications may then pass this to a function that accepts a character pointer such as a regular
expression search or a parser. The pointer should <em>not</em> be written to as that may desynchronize
the internal state of Scintilla.</p>
@@ -4833,6 +4840,15 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){
each replacement then the operation will become O(n^2) rather than O(n). Instead, all
matches should be found and remembered, then all the replacements performed.</p>
+ <p><code>SCI_GETRANGEPOINTER</code> provides direct access to just the
+ range requested. The gap is not moved unless it is within the requested range so this call
+ can be faster than <code>SCI_GETCHARACTERPOINTER</code>.
+ This can be used by application code that is able to act on blocks of text or ranges of lines.</p>
+
+ <p><code>SCI_GETGAPPOSITION</code> returns the current gap position.
+ This is a hint that applications can use to avoid calling <code>SCI_GETRANGEPOINTER</code>
+ with a range that contains the gap and consequent costs of moving the gap.</p>
+
<h2 id="MultipleViews">Multiple views</h2>
<p>A Scintilla window and the document that it displays are separate entities. When you create
diff --git a/include/Scintilla.h b/include/Scintilla.h
index d4da54a9d..e5d545349 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -728,6 +728,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETPOSITIONCACHE 2515
#define SCI_COPYALLOWLINE 2519
#define SCI_GETCHARACTERPOINTER 2520
+#define SCI_GETRANGEPOINTER 2643
+#define SCI_GETGAPPOSITION 2644
#define SCI_SETKEYSUNICODE 2521
#define SCI_GETKEYSUNICODE 2522
#define SCI_INDICSETALPHA 2523
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index ac496dba3..e133be69d 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -1924,6 +1924,15 @@ fun void CopyAllowLine=2519(,)
# characters in the document.
get int GetCharacterPointer=2520(,)
+# Return a read-only pointer to a range of characters in the document.
+# May move the gap so that the range is contiguous, but will only move up
+# to rangeLength bytes.
+get int GetRangePointer=2643(int position, int rangeLength)
+
+# Return a position which, to avoid performance costs, should not be within
+# the range of a call to GetRangePointer.
+get position GetGapPosition=2644(,)
+
# Always interpret keyboard input as Unicode
set void SetKeysUnicode=2521(bool keysUnicode,)
diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx
index 19f6670f6..11b8b4acd 100644
--- a/src/CellBuffer.cxx
+++ b/src/CellBuffer.cxx
@@ -375,6 +375,14 @@ const char *CellBuffer::BufferPointer() {
return substance.BufferPointer();
}
+const char *CellBuffer::RangePointer(int position, int rangeLength) {
+ return substance.RangePointer(position, rangeLength);
+}
+
+int CellBuffer::GapPosition() const {
+ return substance.GapPosition();
+}
+
// The char* returned is to an allocation owned by the undo history
const char *CellBuffer::InsertString(int position, const char *s, int insertLength, bool &startSequence) {
char *data = 0;
diff --git a/src/CellBuffer.h b/src/CellBuffer.h
index a82a3973b..388b9027b 100644
--- a/src/CellBuffer.h
+++ b/src/CellBuffer.h
@@ -157,6 +157,8 @@ public:
char StyleAt(int position) const;
void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const;
const char *BufferPointer();
+ const char *RangePointer(int position, int rangeLength);
+ int GapPosition() const;
int Length() const;
void Allocate(int newSize);
diff --git a/src/Document.h b/src/Document.h
index 18bf00a3d..7e03f3d9e 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -298,6 +298,8 @@ public:
void SetSavePoint();
bool IsSavePoint() { return cb.IsSavePoint(); }
const char * SCI_METHOD BufferPointer() { return cb.BufferPointer(); }
+ const char *RangePointer(int position, int rangeLength) { return cb.RangePointer(position, rangeLength); }
+ int GapPosition() const { return cb.GapPosition(); }
int SCI_METHOD GetLineIndentation(int line);
void SetLineIndentation(int line, int indent);
diff --git a/src/Editor.cxx b/src/Editor.cxx
index c3a4eafb4..8aea4db1d 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -8910,6 +8910,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_GETCHARACTERPOINTER:
return reinterpret_cast<sptr_t>(pdoc->BufferPointer());
+ case SCI_GETRANGEPOINTER:
+ return reinterpret_cast<sptr_t>(pdoc->RangePointer(wParam, lParam));
+
+ case SCI_GETGAPPOSITION:
+ return pdoc->GapPosition();
+
case SCI_SETEXTRAASCENT:
vs.extraAscent = wParam;
InvalidateStyleRedraw();
diff --git a/src/SplitVector.h b/src/SplitVector.h
index 44d5ddc0e..0ccf6c9f4 100644
--- a/src/SplitVector.h
+++ b/src/SplitVector.h
@@ -261,6 +261,24 @@ public:
body[lengthBody] = 0;
return body;
}
+
+ T *RangePointer(int position, int rangeLength) {
+ if (position < part1Length) {
+ if ((position + rangeLength) > part1Length) {
+ // Range overlaps gap, so move gap to start of range.
+ GapTo(position);
+ return body + position + gapLength;
+ } else {
+ return body + position ;
+ }
+ } else {
+ return body + position + gapLength;
+ }
+ }
+
+ int GapPosition() const {
+ return part1Length;
+ }
};
#endif
diff --git a/test/simpleTests.py b/test/simpleTests.py
index fe1589725..5ad5cf987 100644
--- a/test/simpleTests.py
+++ b/test/simpleTests.py
@@ -1231,7 +1231,7 @@ class TestAutoComplete(unittest.TestCase):
self.ed = self.xite.ed
self.ed.ClearAll()
self.ed.EmptyUndoBuffer()
- # 3 lines of 3 characters
+ # 1 line of 3 characters
t = b"xxx\n"
self.ed.AddText(len(t), t)
@@ -1310,6 +1310,36 @@ class TestAutoComplete(unittest.TestCase):
self.assertEquals(self.ed.AutoCActive(), 0)
+class TestDirectAccess(unittest.TestCase):
+
+ def setUp(self):
+ self.xite = XiteWin.xiteFrame
+ self.ed = self.xite.ed
+ self.ed.ClearAll()
+ self.ed.EmptyUndoBuffer()
+
+ def testGapPosition(self):
+ text = b"abcd"
+ self.ed.SetText(len(text), text)
+ self.assertEquals(self.ed.GapPosition, 4)
+ self.ed.TargetStart = 1
+ self.ed.TargetEnd = 1
+ rep = b"-"
+ self.ed.ReplaceTarget(len(rep), rep)
+ self.assertEquals(self.ed.GapPosition, 2)
+
+ def testCharacterPointerAndRangePointer(self):
+ text = b"abcd"
+ self.ed.SetText(len(text), text)
+ characterPointer = self.ed.CharacterPointer
+ rangePointer = self.ed.GetRangePointer(0,3)
+ self.assertEquals(characterPointer, rangePointer)
+ cpBuffer = ctypes.c_char_p(characterPointer)
+ self.assertEquals(cpBuffer.value, text)
+ # Gap will not be moved as already moved for CharacterPointer call
+ rangePointer = self.ed.GetRangePointer(1,3)
+ cpBuffer = ctypes.c_char_p(rangePointer)
+ self.assertEquals(cpBuffer.value, text[1:])
#~ import os
#~ for x in os.getenv("PATH").split(";"):