diff options
author | nyamatongwe <devnull@localhost> | 2012-05-26 15:15:07 +1000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2012-05-26 15:15:07 +1000 |
commit | 1596a6d6b4540980cd6a8249460d881d6d190c1f (patch) | |
tree | 498aeab1fe1cf973892c069753d8d06ea5420785 | |
parent | 25e91c5a5870ea1138684dbd2d67888bccce5876 (diff) | |
download | scintilla-mirror-1596a6d6b4540980cd6a8249460d881d6d190c1f.tar.gz |
Add GetRangePointer and GetGapPosition methods.
-rw-r--r-- | doc/ScintillaDoc.html | 20 | ||||
-rw-r--r-- | include/Scintilla.h | 2 | ||||
-rw-r--r-- | include/Scintilla.iface | 9 | ||||
-rw-r--r-- | src/CellBuffer.cxx | 8 | ||||
-rw-r--r-- | src/CellBuffer.h | 2 | ||||
-rw-r--r-- | src/Document.h | 2 | ||||
-rw-r--r-- | src/Editor.cxx | 6 | ||||
-rw-r--r-- | src/SplitVector.h | 18 | ||||
-rw-r--r-- | test/simpleTests.py | 32 |
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(";"): |