diff options
| -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(";"): | 
